\chapter{Keras新手指南}\label{ch:指南}
\section{Keras FAQ：常见问题}
\begin{itemize}
    \item \nameref{sec:FAQ1}
    \item \nameref{sec:FAQ2}
    \item \nameref{sec:FAQ3}
    \item \nameref{sec:FAQ4}
    \item \nameref{sec:FAQ5}
    \item \nameref{sec:FAQ6}
    \item \nameref{sec:FAQ7}
    \item \nameref{sec:FAQ8}
    \item \nameref{sec:FAQ9}
    \item \nameref{sec:FAQ10}
    \item \nameref{sec:FAQ11}
    \item \nameref{sec:FAQ12}
    \item \nameref{sec:FAQ13}
    \item \nameref{sec:FAQ14}
    \item \nameref{sec:FAQ15}
    \item \nameref{sec:FAQ16}
    \item \nameref{sec:FAQ17}
    \item \nameref{sec:FAQ18}
\end{itemize}

\section{如何引用Keras？}\label{sec:FAQ1}
如果Keras对你的研究有帮助的话，请在你的文章中引用Keras。这里是一个使用BibTex的例子
\begin{latexcode}
@misc{chollet2015keras,
    author = {Chollet, François and others},
    title = {Keras},
    year = {2015},
    publisher = {GitHub},
    journal = {GitHub repository},
    howpublished = {\url{https://github.com/fchollet/keras}}
}
\end{latexcode}

\section{如何使Keras调用GPU？}\label{sec:FAQ2}


如果采用TensorFlow作为后端，当机器上有可用的GPU时，代码会自动调用GPU进行并行计算。如果使用Theano作为后端，可以通过以下方法设置：
\begin{enumerate}
\item[方法1]：使用Theano标记,在执行python脚本时使用下面的命令：
\begin{bashcode}
{THEANO_FLAGS=device=gpu,
floatX=float32
python my_keras_script.py}
\end{bashcode}
\item[方法2]：设置.theano文件,点击这里查看\href{http://deeplearning.net/software/theano/library/config.html}{这里}指导教程

\item[方法3]：在代码的开头处手动设置theano.config.device和theano.config.floatX
\begin{python}
import theano
theano.config.device = 'gpu'
theano.config.floatX = 'float32'
\end{python}
\end{enumerate}
\section{"batch", "epoch"和"sample"都是啥意思？}\label{sec:FAQ3}


下面是一些使用keras时常会遇到的概念，我们来简单解释。

Sample：样本，数据集中的一条数据。例如图片数据集中的一张图片，语音数据中的一段音频。

Batch：中文为批，一个batch由若干条数据构成。batch是进行网络优化的基本单位，网络\textbf{参数}的每一轮优化需要使用一个batch。batch中的样本是被并行处理的。与单个样本相比，一个batch的数据能更好的模拟数据集的分布，batch越大则对输入数据分布模拟的越好，反应在网络训练上，则体现为能让网络训练的方向“更加正确”。但另一方面，一个batch也只能让网络的参数更新一次，因此网络参数的迭代会较慢。在测试网络的时候，应该在条件的允许的范围内尽量使用更大的batch，这样计算效率会更高。

Epoch，epoch可译为“轮次”。如果说每个batch对应网络的一次更新的话，一个epoch对应的就是网络的一轮更新。每一轮更新中网络更新的次数可以随意，但通常会设置为遍历一遍数据集。因此一个epoch的含义是模型完整的看了一遍数据集。 设置epoch的主要作用是把模型的训练的整个训练过程分为若干个段，这样我们可以更好的观察和调整模型的训练。Keras中，当指定了验证集时，每个epoch执行完后都会运行一次验证集以确定模型的性能。另外，我们可以使用回调函数在每个epoch的训练前后执行一些操作，如调整学习率，打印目前模型的一些信息等，详情请参考\nameref{ch:callbacks}一节。

\section{如何保存Keras模型？}\label{sec:FAQ4}


我们不推荐使用pickle或cPickle来保存Keras模型

你可以使用model.save(filepath)将Keras模型和权重保存在一个HDF5文件中，该文件将包含：

模型的结构，以便重构该模型
模型的权重
训练配置（损失函数，优化器等）
优化器的状态，以便于从上次训练中断的地方开始
使用keras.models.load\_model(filepath)来重新实例化你的模型，如果文件中存储了训练配置的话，该函数还会同时完成模型的编译

例子：
\begin{python}
from keras.models import load_model

model.save('my_model.h5')  # creates a HDF5 file 'my_model.h5'
del model  # deletes the existing model

# returns a compiled model
# identical to the previous one
model = load_model('my_model.h5')
\end{python}
如果你只是希望保存模型的结构，而不包含其权重或配置信息，可以使用：
\begin{bashcode}
# save as JSON
json_string = model.to_json()

# save as YAML
yaml_string = model.to_yaml()
\end{bashcode}
这项操作将把模型序列化为json或yaml文件，这些文件对人而言也是友好的，如果需要的话你甚至可以手动打开这些文件并进行编辑。

当然，你也可以从保存好的json文件或yaml文件中载入模型：
\begin{python}
# model reconstruction from JSON:
from keras.models import model_from_json
model = model_from_json(json_string)

# model reconstruction from YAML
model = model_from_yaml(yaml_string)
\end{python}
如果需要保存模型的权重，可通过下面的代码利用HDF5进行保存。注意，在使用前需要确保你已安装了HDF5和其Python库h5py

\pythoninline{model.save_weights('my_model_weights.h5')}
如果你需要在代码中初始化一个完全相同的模型，请使用：

\pythoninline{model.load_weights('my_model_weights.h5')}
如果你需要加载权重到不同的网络结构（有些层一样）中，例如fine-tune或transfer-learning，你可以通过层名字来加载模型：

\pythoninline{model.load_weights('my_model_weights.h5', by_name=True)}
例如：
假如原模型为：
\begin{python}
model = Sequential()
model.add(Dense(2, input_dim=3, name="dense_1"))
model.add(Dense(3, name="dense_2"))
...
model.save_weights(fname)
# new model
model = Sequential()
model.add(Dense(2, input_dim=3, name="dense_1"))  # will be loaded
model.add(Dense(10, name="new_dense"))  # will not be loaded

# load weights from first model; will only affect the first layer, dense_1.
model.load_weights(fname, by_name=True)
\end{python}

\section{为什么训练误差比测试误差高很多？}\label{sec:FAQ5}


一个Keras的模型有两个模式：训练模式和测试模式。一些正则机制，如Dropout，L1/L2正则项在测试模式下将不被启用。

另外，训练误差是训练数据每个batch的误差的平均。在训练过程中，每个epoch起始时的batch的误差要大一些，而后面的batch的误差要小一些。另一方面，每个epoch结束时计算的测试误差是由模型在epoch结束时的状态决定的，这时候的网络将产生较小的误差。

\begin{remark}
    可以通过定义回调函数将每个epoch的训练误差和测试误差并作图，如果训练误差曲线和测试误差曲线之间有很大的空隙，说明你的模型可能有过拟合的问题。当然，这个问题与Keras无关。
\end{remark}

\section{如何获取中间层的输出？}\label{sec:FAQ6}


一种简单的方法是创建一个新的Model，使得它的输出是你想要的那个输出
\begin{python}
from keras.models import Model

model = ...  # create the original model

layer_name = 'my_layer'
intermediate_layer_model = Model(input=model.input,
output=model.get_layer(layer_name).output)
intermediate_output = intermediate_layer_model.predict(data
\end{python}
此外，我们也可以建立一个Keras的函数来达到这一目的：
\begin{python}
from keras import backend as K

# with a Sequential model
get_3rd_layer_output = K.function([model.layers[0].input],
[model.layers[3].output])
layer_output = get_3rd_layer_output([X])[0]
\end{python}
当然，我们也可以直接编写Theano和TensorFlow的函数来完成这件事

注意，如果你的模型在训练和测试两种模式下不完全一致，例如你的模型中含有Dropout层，批规范化（BatchNormalization）层等组件，你需要在函数中传递一个learning\_phase的标记，像这样：
\begin{python}
get_3rd_layer_output = K.function([model.layers[0].input, K.learning_phase()],
[model.layers[3].output])

# output in test mode = 0
layer_output = get_3rd_layer_output([X, 0])[0]

# output in train mode = 1
layer_output = get_3rd_layer_output([X, 1])[0]
\end{python}
\section{如何利用Keras处理超过机器内存的数据集？}\label{sec:FAQ7}


可以使用model.train\_on\_batch(X,y)和model.test\_on\_batch(X,y)。请参考\nameref{ch:model}

另外，也可以编写一个每次产生一个batch样本的生成器函数，并调用model.fit\_generator(data\_generator, samples\_per\_epoch, nb\_epoch)进行训练

这种方式在Keras代码包的example文件夹下CIFAR10例子里有示范，也可点击\href{https://github.com/fchollet/keras/blob/master/examples/cifar10_cnn.py}{这里}在github上浏览。


\section{当验证集的loss不再下降时，如何中断训练？}\label{sec:FAQ8}


可以定义EarlyStopping来提前终止训练
\begin{python}
from keras.callbacks import EarlyStopping
early_stopping = EarlyStopping(monitor='val_loss', patience=2)
model.fit(X, y, validation_split=0.2, callbacks=[early_stopping])
\end{python}
请参考回调函数


\section{验证集是如何从训练集中分割出来的？}\label{sec:FAQ9}


如果在model.fit中设置validation\_spilt的值，则可将数据分为训练集和验证集，例如，设置该值为0.1，则训练集的最后10\%数据将作为验证集，设置其它数字同理。注意，原数据在进行验证集分割前并没有被shuffle，所以这里的验证集严格的就是你输入数据最末的x\%。


\section{训练数据在训练时会被随机洗乱吗？}\label{sec:FAQ10}


是的，如果model.fit的shuffle参数为真，训练的数据就会被随机洗乱。不设置时默认为真。训练数据会在每个epoch的训练中都重新洗乱一次。

验证集的数据不会被洗乱


\section{如何在每个epoch后记录训练/测试的loss和正确率？}\label{sec:FAQ11}


model.fit在运行结束后返回一个History对象，其中含有的history属性包含了训练过程中损失函数的值以及其它度量指标。
\begin{python}
hist = model.fit(X, y, validation_split=0.2)
print(hist.history)
\end{python}
\section{如何使用状态RNN（statful RNN）？}\label{sec:FAQ12}


一个RNN是状态RNN，意味着训练时每个batch的状态都会被重用于初始化下一个batch的初始状态。

当使用状态RNN时，有如下假设

所有的batch都具有相同数目的样本
如果X1和X2是两个相邻的batch，那么对于任何i，X2[i]都是X1[i]的后续序列
要使用状态RNN，我们需要显式的指定每个batch的大小。可以通过模型的首层参数batch\_input\_shape来完成。batch\_input\_shape是一个整数tuple，例如(32,10,16)代表一个具有10个时间步，每步向量长为16，每32个样本构成一个batch的输入数据格式。
在RNN层中，设置stateful=True
要重置网络的状态，使用：
\begin{itemize}
\item model.reset\_states()来重置网络中所有层的状态
\item layer.reset\_states()来重置指定层的状态
\end{itemize}
例子：
\begin{python}
# this is our input data, of shape (32, 21, 16)
# we will feed it to our model in sequences of length 10

model = Sequential()
model.add(LSTM(32, input_shape=(10, 16), batch_size=32, stateful=True))
model.add(Dense(16, activation='softmax'))

model.compile(optimizer='rmsprop', loss='categorical_crossentropy')

# we train the network to predict the 11th timestep given the first 10:
model.train_on_batch(X[:, :10, :], np.reshape(X[:, 10, :], (32, 16)))

# the state of the network has changed. We can feed the follow-up sequences:
model.train_on_batch(X[:, 10:20, :], np.reshape(X[:, 20, :], (32, 16)))

# let's reset the states of the LSTM layer:
model.reset_states()

# another way to do it in this case:
model.layers[0].reset_states()
\end{python}
注意，predict，fit，train\_on\_batch ，predict\_classes等方法都会更新模型中状态层的状态。这使得你可以不但可以进行状态网络的训练，也可以进行状态网络的预测。


\section{如何“冻结”网络的层？}\label{sec:FAQ13}


“冻结”一个层指的是该层将不参加网络训练，即该层的权重永不会更新。在进行fine-tune时我们经常会需要这项操作。 在使用固定的embedding层处理文本输入时，也需要这个技术。

可以通过向层的构造函数传递trainable参数来指定一个层是不是可训练的，如：

frozen\_layer = Dense(32,trainable=False)
此外，也可以通过将层对象的trainable属性设为True或False来为已经搭建好的模型设置要冻结的层。 在设置完后，需要运行compile来使设置生效，例如：
\begin{python}
x = Input(shape=(32,))
layer = Dense(32)
layer.trainable = False
y = layer(x)

frozen_model = Model(x, y)
# in the model below, the weights of `layer` will not be updated during training
frozen_model.compile(optimizer='rmsprop', loss='mse')

layer.trainable = True
trainable_model = Model(x, y)
# with this model the weights of the layer will be updated during training
# (which will also affect the above model since it uses the same layer instance)
trainable_model.compile(optimizer='rmsprop', loss='mse')

frozen_model.fit(data, labels)  # this does NOT update the weights of `layer`
trainable_model.fit(data, labels)  # this updates the weights of `layer`
\end{python}
\section{如何从Sequential模型中去除一个层？}\label{sec:FAQ14}


可以通过调用.pop()来去除模型的最后一个层，反复调用n次即可去除模型后面的n个层
\begin{python}
model = Sequential()
model.add(Dense(32, activation='relu', input_dim=784))
model.add(Dense(32, activation='relu'))

print(len(model.layers))  # "2"

model.pop()
print(len(model.layers))  # "1"
\end{python}
\section{如何在Keras中使用预训练的模型？}\label{sec:FAQ15}


我们提供了下面这些图像分类的模型代码及预训练权重：
\begin{itemize}
\item VGG16
\item VGG19
\item ResNet50
\item Inception v3
\end{itemize}
可通过keras.applications载入这些模型：
\begin{python}
from keras.applications.vgg16 import VGG16
from keras.applications.vgg19 import VGG19
from keras.applications.resnet50 import ResNet50
from keras.applications.inception_v3 import InceptionV3

model = VGG16(weights='imagenet', include_top=True)
\end{python}
这些代码的使用示例请参考.Application模型的文档

使用这些预训练模型进行特征抽取或fine-tune的例子可以参考\href{https://blog.keras.io/building-powerful-image-classification-models-using-very-little-data.html}{此博客}

VGG模型也是很多Keras例子的基础模型，如：
\begin{itemize}
\item Style-transfer
\item Feature visualization
\item Deep dream
\end{itemize}
\section{如何在Keras中使用HDF5输入？}\label{sec:FAQ16}


你可以使用keras.utils中的HDF5Matrix类来读取HDF5输入，参考这里\nameref{ch:utils}

可以直接使用HDF5数据库，示例
\begin{python}
import h5py
with h5py.File('input/file.hdf5', 'r') as f:
X_data = f['X_data']
model.predict(X_data)
\end{python}
\section{Keras的配置文件存储在哪里？}\label{sec:FAQ17}


所有的Keras数据默认存储在：

\$HOME/.keras/
对windows用户而言，\$HOME应替换为\%USERPROFILE\%

当Keras无法在上面的位置创建文件夹时（例如由于权限原因），备用的地址是/tmp/.keras/

Keras配置文件为JSON格式的文件，保存在\$HOME/.keras/keras.json。默认的配置文件长这样：
\begin{bashcode}
{
    "image_data_format": "channels_last",
    "epsilon": 1e-07,
    "floatx": "float32",
    "backend": "tensorflow"
}
\end{bashcode}
该文件包含下列字段：

默认的图像数据格式channels\_last或channels\_first
用于防止除零错误的epsilon
默认的浮点数类型
默认的后端
类似的，缓存的数据集文件，即由get\_file()下载的文件，默认保存在\$HOME/.keras/datasets/


\section{在使用Keras开发过程中，我如何获得可复现的结果?}\label{sec:FAQ18}


在开发模型中，有时取得可复现的结果是很有用的。例如，这可以帮助我们定位模型性能的改变是由模型本身引起的还是由于数据上的变化引起的。下面的代码展示了如何获得可复现的结果，该代码基于Python3的tensorflow后端
\begin{python}
import numpy as np
import tensorflow as tf
import random as rn

# The below is necessary in Python 3.2.3 onwards to
# have reproducible behavior for certain hash-based operations.
# See these references for further details:
# https://docs.python.org/3.4/using/cmdline.html#envvar-PYTHONHASHSEED
# https://github.com/fchollet/keras/issues/2280#issuecomment-306959926

import os
os.environ['PYTHONHASHSEED'] = '0'

# The below is necessary for starting Numpy generated random numbers
# in a well-defined initial state.

np.random.seed(42)

# The below is necessary for starting core Python generated random numbers
# in a well-defined state.

rn.seed(12345)

# Force TensorFlow to use single thread.
# Multiple threads are a potential source of
# non-reproducible results.
# For further details, see: https://stackoverflow.com/questions/42022950/which-seeds-have-to-be-set-where-to-realize-100-reproducibility-of-training-res

session_conf = tf.ConfigProto(intra_op_parallelism_threads=1, inter_op_parallelism_threads=1)

from keras import backend as K

# The below tf.set_random_seed() will make random number generation
# in the TensorFlow backend have a well-defined initial state.
# For further details, see: https://www.tensorflow.org/api_docs/python/tf/set_random_seed

tf.set_random_seed(1234)

sess = tf.Session(graph=tf.get_default_graph(), config=session_conf)
K.set_session(sess)

# Rest of code follows ...
\end{python}
\chapter{Keras}
Keras是一个高层神经网络API，Keras由纯Python编写而成并基Tensorflow、Theano以及CNTK后端。Keras 为支持快速实验而生，能够把你的idea迅速转换为结果，如果你有如下需求，请选择Keras：
\begin{itemize}
\item 简易和快速的原型设计（keras具有高度模块化，极简，和可扩充特性）
\item 支持CNN和RNN，或二者的结合
\item 无缝CPU和GPU切换
\item Keras适用的Python版本是：Python 2.7-3.5
\end{itemize}
\textbf{Keras设计原则}
\begin{itemize}
    \item 用户友好：Keras是为人类而不是天顶星人设计的API。用户的使用体验始终是我们考虑的首要和中心内容。Keras遵循减少认知困难的最佳实践：Keras提供一致而简洁的API， 能够极大减少一般应用下用户的工作量，同时，Keras提供清晰和具有实践意义的bug反馈。
    \item 模块性：模型可理解为一个层的序列或数据的运算图，完全可配置的模块可以用最少的代价自由组合在一起。具体而言，网络层、损失函数、优化器、初始化策略、激活函数、正则化方法都是独立的模块，你可以使用它们来构建自己的模型。
    \item 易扩展性：添加新模块超级容易，只需要仿照现有的模块编写新的类或函数即可。创建新模块的便利性使得Keras更适合于先进的研究工作。
    \item 与Python协作：Keras没有单独的模型配置文件类型（作为对比，caffe有），模型由python代码描述，使其更紧凑和更易debug，并提供了扩展的便利性。
\end{itemize}
\section{30快速上手Keras}
Keras的核心数据结构是“模型”，模型是一种组织网络层的方式。Keras中主要的模型是Sequential模型，Sequential是一系列网络层按顺序构成的栈。你也可以查看函数式模型来学习建立更复杂的模型

Sequential模型如下：
\begin{python}
from keras.models import Sequential
model = Sequential()
\end{python}
将一些网络层通过.add()堆叠起来，就构成了一个模型：
\begin{python}
from keras.layers import Dense, Activation

model.add(Dense(units=64, input_dim=100))
model.add(Activation("relu"))
model.add(Dense(units=10))
model.add(Activation("softmax"))
\end{python}
完成模型的搭建后，我们需要使用.compile()方法来编译模型：

model.compile(loss='categorical\_crossentropy', optimizer='sgd', metrics=['accuracy'])
编译模型时必须指明损失函数和优化器，如果你需要的话，也可以自己定制损失函数。Keras的一个核心理念就是简明易用同时，保证用户对Keras的绝对控制力度，用户可以根据自己的需要定制自己的模型、网络层，甚至修改源代码。
\begin{python}
from keras.optimizers import SGD
model.compile(loss='categorical_crossentropy', optimizer=SGD(lr=0.01, momentum=0.9, nesterov=True))
\end{python}
完成模型编译后，我们在训练数据上按batch进行一定次数的迭代来训练网络

model.fit(x\_train, y\_train, epochs=5, batch\_size=32)
当然，我们也可以手动将一个个batch的数据送入网络中训练，这时候需要使用：
\begin{python}
model.train_on_batch(x_batch, y_batch)
\end{python}
随后，我们可以使用一行代码对我们的模型进行评估，看看模型的指标是否满足我们的要求：
\begin{python}
loss_and_metrics = model.evaluate(x_test, y_test, batch_size=128)
\end{python}
或者，我们可以使用我们的模型，对新的数据进行预测：
\begin{python}
classes = model.predict(x_test, batch_size=128)
\end{python}
搭建一个问答系统、图像分类模型或神经图灵机、word2vec词嵌入器就是这么快。支撑深度学习的基本想法本就是简单的，现在让我们把它的实现也变的简单起来！

为了更深入的了解Keras，我们建议你查看一下下面的两个tutorial
\begin{itemize}
    \item \nameref{sec:Sequential}
    \item \nameref{sec:Functional}
\end{itemize}
还有我们的新手教程，虽然是面向新手的，但我们阅读它们总是有益的：

\nameref{ch:指南}
在Keras代码包的examples文件夹里，我们提供了一些更高级的模型：基于记忆网络的问答系统、基于LSTM的文本的文本生成等。
\chapter{快速开始}
\section{快速开始序贯（Sequential）模型}\label{sec:Sequential}
序贯模型是多个网络层的线性堆叠，也就是“一条路走到黑”。
可以通过向Sequential模型传递一个layer的list来构造该模型：
\begin{python}
from keras.models import Sequential
from keras.layers import Dense, Activation

model = Sequential([
Dense(32, units=784),
Activation('relu'),
Dense(10),
Activation('softmax'),
])
\end{python}
也可以通过.add()方法一个个的将layer加入模型中：
\begin{python}
model = Sequential()
model.add(Dense(32, input_shape=(784,)))
model.add(Activation('relu'))
\end{python}
指定输入数据的shape

模型需要知道输入数据的shape，因此，Sequential的第一层需要接受一个关于输入数据shape的参数，后面的各个层则可以自动的推导出中间数据的shape，因此不需要为每个层都指定这个参数。有几种方法来为第一层指定输入数据的shape

传递一个input\_shape的关键字参数给第一层，input\_shape是一个tuple类型的数据，其中也可以填入None，如果填入None则表示此位置可能是任何正整数。数据的batch大小不应包含在其中。
有些2D层，如Dense，支持通过指定其输入维度input\_dim来隐含的指定输入数据shape。一些3D的时域层支持通过参数input\_dim和input\_length来指定输入shape。
如果你需要为输入指定一个固定大小的batch\_size（常用于stateful RNN网络），可以传递batch\_size参数到一个层中，例如你想指定输入张量的batch大小是32，数据shape是（6，8），则你需要传递batch\_size=32和input\_shape=(6,8)。
\begin{python}
model = Sequential()
model.add(Dense(32, input_dim=784))
\end{python}
编译

在训练模型之前，我们需要通过compile来对学习过程进行配置。compile接收三个参数：
\begin{itemize}
	\item 优化器optimizer：该参数可指定为已预定义的优化器名，如rmsprop、adagrad，或一个Optimizer类的对象，详情见\nameref{ch:优化器}
	\item 损失函数loss：该参数为模型试图最小化的目标函数，它可为预定义的损失函数名，如categorical\_crossentropy、mse，也可以为一个损失函数。详情见losses
	\item 指标列表metrics：对分类问题，我们一般将该列表设置为metrics=['accuracy']。指标可以是一个预定义指标的名字,也可以是一个用户定制的函数.指标函数应该返回单个张量,或一个完成metric\_name - > metric\_value映射的字典.请参考性能评估
\end{itemize}
\begin{python}
# For a multi-class classification problem
model.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# For a binary classification problem
model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy'])

# For a mean squared error regression problem
model.compile(optimizer='rmsprop',
              loss='mse')

# For custom metrics
import keras.backend as K

def mean_pred(y_true, y_pred):
    return K.mean(y_pred)

model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy', mean_pred])
\end{python}
训练

Keras以Numpy数组作为输入数据和标签的数据类型。训练模型一般使用fit函数，该函数的详情见\nameref{sec:Sequential API}。下面是一些例子。
\begin{python}
# For a single-input model with 2 classes (binary classification):

model = Sequential()
model.add(Dense(32, activation='relu', input_dim=100))
model.add(Dense(1, activation='sigmoid'))
model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy'])

# Generate dummy data
import numpy as np
data = np.random.random((1000, 100))
labels = np.random.randint(2, size=(1000, 1))

# Train the model, iterating on the data in batches of 32 samples
model.fit(data, labels, epochs=10, batch_size=32)
# For a single-input model with 10 classes (categorical classification):

model = Sequential()
model.add(Dense(32, activation='relu', input_dim=100))
model.add(Dense(10, activation='softmax'))
model.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# Generate dummy data
import numpy as np
data = np.random.random((1000, 100))
labels = np.random.randint(10, size=(1000, 1))

# Convert labels to categorical one-hot encoding
one_hot_labels = keras.utils.to_categorical(labels, num_classes=10)

# Train the model, iterating on the data in batches of 32 samples
model.fit(data, one_hot_labels, epochs=10, batch_size=32)
\end{python}
这里是一些帮助你开始的例子，在Keras代码包的examples文件夹中，你将找到使用真实数据的示例模型：
\begin{itemize}
	\item CIFAR10 小图片分类：使用CNN和实时数据提升
	\item IMDB 电影评论观点分类：使用LSTM处理成序列的词语
	\item Reuters（路透社）新闻主题分类：使用多层感知器（MLP）
	\item MNIST手写数字识别：使用多层感知器和CNN
	\item 字符级文本生成：使用LSTM ...
\end{itemize}
基于多层感知器的softmax多分类：

\begin{python}
from keras.models import Sequential
from keras.layers import Dense, Dropout, Activation
from keras.optimizers import SGD

# Generate dummy data
import numpy as np
x_train = np.random.random((1000, 20))
y_train = keras.utils.to_categorical(np.random.randint(10, size=(1000, 1)), num_classes=10)
x_test = np.random.random((100, 20))
y_test = keras.utils.to_categorical(np.random.randint(10, size=(100, 1)), num_classes=10)

model = Sequential()
# Dense(64) is a fully-connected layer with 64 hidden units.
# in the first layer, you must specify the expected input data shape:
# here, 20-dimensional vectors.
model.add(Dense(64, activation='relu', input_dim=20))
model.add(Dropout(0.5))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))

sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy',
              optimizer=sgd,
              metrics=['accuracy'])

model.fit(x_train, y_train,
          epochs=20,
          batch_size=128)
score = model.evaluate(x_test, y_test, batch_size=128)
\end{python}
MLP的二分类：
\begin{python}
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Dropout

# Generate dummy data
x_train = np.random.random((1000, 20))
y_train = np.random.randint(2, size=(1000, 1))
x_test = np.random.random((100, 20))
y_test = np.random.randint(2, size=(100, 1))

model = Sequential()
model.add(Dense(64, input_dim=20, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])
model.fit(x_train, y_train,
          epochs=20,
          batch_size=128)
score = model.evaluate(x_test, y_test, batch_size=128)
\end{python}
类似VGG的卷积神经网络：
\begin{python}
import numpy as np
import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Conv2D, MaxPooling2D
from keras.optimizers import SGD

# Generate dummy data
x_train = np.random.random((100, 100, 100, 3))
y_train = keras.utils.to_categorical(np.random.randint(10, size=(100, 1)), num_classes=10)
x_test = np.random.random((20, 100, 100, 3))
y_test = keras.utils.to_categorical(np.random.randint(10, size=(20, 1)), num_classes=10)

model = Sequential()
# input: 100x100 images with 3 channels -> (100, 100, 3) tensors.
# this applies 32 convolution filters of size 3x3 each.
model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(100, 100, 3)))
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(10, activation='softmax'))

sgd = SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='categorical_crossentropy', optimizer=sgd)

model.fit(x_train, y_train, batch_size=32, epochs=10)
score = model.evaluate(x_test, y_test, batch_size=32)
\end{python}
使用LSTM的序列分类
\begin{python}
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.layers import Embedding
from keras.layers import LSTM

model = Sequential()
model.add(Embedding(max_features, output_dim=256))
model.add(LSTM(128))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

model.fit(x_train, y_train, batch_size=16, epochs=10)
score = model.evaluate(x_test, y_test, batch_size=16)
\end{python}
使用1D卷积的序列分类
\begin{python}
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.layers import Embedding
from keras.layers import Conv1D, GlobalAveragePooling1D, MaxPooling1D

model = Sequential()
model.add(Conv1D(64, 3, activation='relu', input_shape=(seq_length, 100)))
model.add(Conv1D(64, 3, activation='relu'))
model.add(MaxPooling1D(3))
model.add(Conv1D(128, 3, activation='relu'))
model.add(Conv1D(128, 3, activation='relu'))
model.add(GlobalAveragePooling1D())
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

model.fit(x_train, y_train, batch_size=16, epochs=10)
score = model.evaluate(x_test, y_test, batch_size=16)
\end{python}
用于序列分类的栈式LSTM

在该模型中，我们将三个LSTM堆叠在一起，是该模型能够学习更高层次的时域特征表示。

开始的两层LSTM返回其全部输出序列，而第三层LSTM只返回其输出序列的最后一步结果，从而其时域维度降低（即将输入序列转换为单个向量）
\begin{python}
#regular_stacked_lstm

from keras.models import Sequential
from keras.layers import LSTM, Dense
import numpy as np

data_dim = 16
timesteps = 8
num_classes = 10

# expected input data shape: (batch_size, timesteps, data_dim)
model = Sequential()
model.add(LSTM(32, return_sequences=True,
               input_shape=(timesteps, data_dim)))  # returns a sequence of vectors of dimension 32
model.add(LSTM(32, return_sequences=True))  # returns a sequence of vectors of dimension 32
model.add(LSTM(32))  # return a single vector of dimension 32
model.add(Dense(10, activation='softmax'))

model.compile(loss='categorical_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

# Generate dummy training data
x_train = np.random.random((1000, timesteps, data_dim))
y_train = np.random.random((1000, num_classes))

# Generate dummy validation data
x_val = np.random.random((100, timesteps, data_dim))
y_val = np.random.random((100, num_classes))

model.fit(x_train, y_train,
          batch_size=64, epochs=5,
          validation_data=(x_val, y_val))
\end{python}
采用stateful LSTM的相同模型

stateful LSTM的特点是，在处理过一个batch的训练数据后，其内部状态（记忆）会被作为下一个batch的训练数据的初始状态。状态LSTM使得我们可以在合理的计算复杂度内处理较长序列

请FAQ中关于\nameref{sec:FAQ12}获取更多信息
\begin{python}
from keras.models import Sequential
from keras.layers import LSTM, Dense
import numpy as np

data_dim = 16
timesteps = 8
num_classes = 10
batch_size = 32

# Expected input batch shape: (batch_size, timesteps, data_dim)
# Note that we have to provide the full batch_input_shape since the network is stateful.
# the sample of index i in batch k is the follow-up for the sample i in batch k-1.
model = Sequential()
model.add(LSTM(32, return_sequences=True, stateful=True,
               batch_input_shape=(batch_size, timesteps, data_dim)))
model.add(LSTM(32, return_sequences=True, stateful=True))
model.add(LSTM(32, stateful=True))
model.add(Dense(10, activation='softmax'))

model.compile(loss='categorical_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

# Generate dummy training data
x_train = np.random.random((batch_size * 10, timesteps, data_dim))
y_train = np.random.random((batch_size * 10, num_classes))

# Generate dummy validation data
x_val = np.random.random((batch_size * 3, timesteps, data_dim))
y_val = np.random.random((batch_size * 3, num_classes))

model.fit(x_train, y_train,
          batch_size=batch_size, epochs=5, shuffle=False,
          validation_data=(x_val, y_val))
\end{python}
\section{快速开始函数式（Functional）模型}\label{sec:Functional}


我们起初将Functional一词译作泛型，想要表达该类模型能够表达任意张量映射的含义，但表达的不是很精确，在Keras 2里我们将这个词改译为“函数式”，对函数式编程有所了解的同学应能够快速get到该类模型想要表达的含义。函数式模型称作Functional，但它的类名是Model，因此我们有时候也用Model来代表函数式模型。

Keras函数式模型接口是用户定义多输出模型、非循环有向模型或具有共享层的模型等复杂模型的途径。一句话，只要你的模型不是类似VGG一样一条路走到黑的模型，或者你的模型需要多于一个的输出，那么你总应该选择函数式模型。函数式模型是最广泛的一类模型，序贯模型（Sequential）只是它的一种特殊情况。

这部分的文档假设你已经对Sequential模型已经比较熟悉

让我们从简单一点的模型开始

\subsubsection{第一个模型：全连接网络}\label{subsec:全连接网络}

Sequential当然是实现全连接网络的最好方式，但我们从简单的全连接网络开始，有助于我们学习这部分的内容。在开始前，有几个概念需要澄清：

层对象接受张量为参数，返回一个张量。
输入是张量，输出也是张量的一个框架就是一个模型，通过Model定义。
这样的模型可以被像Keras的Sequential一样被训练
\begin{python}
from keras.layers import Input, Dense
from keras.models import Model

# This returns a tensor
inputs = Input(shape=(784,))

# a layer instance is callable on a tensor, and returns a tensor
x = Dense(64, activation='relu')(inputs)
x = Dense(64, activation='relu')(x)
predictions = Dense(10, activation='softmax')(x)

# This creates a model that includes
# the Input layer and three Dense layers
model = Model(inputs=inputs, outputs=predictions)
model.compile(optimizer='rmsprop',
              loss='categorical_crossentropy',
              metrics=['accuracy'])
model.fit(data, labels)  # starts training
\end{python}
所有的模型都是可调用的，就像层一样

利用函数式模型的接口，我们可以很容易的重用已经训练好的模型：你可以把模型当作一个层一样，通过提供一个tensor来调用它。注意当你调用一个模型时，你不仅仅重用了它的结构，也重用了它的权重。
\begin{python}
x = Input(shape=(784,))
# This works, and returns the 10-way softmax we defined above.
y = model(x)
\end{python}
这种方式可以允许你快速的创建能处理序列信号的模型，你可以很快将一个图像分类的模型变为一个对视频分类的模型，只需要一行代码：
\begin{python}
from keras.layers import TimeDistributed

# Input tensor for sequences of 20 timesteps,
# each containing a 784-dimensional vector
input_sequences = Input(shape=(20, 784))

# This applies our previous model to every timestep in the input sequences.
# the output of the previous model was a 10-way softmax,
# so the output of the layer below will be a sequence of 20 vectors of size 10.
processed_sequences = TimeDistributed(model)(input_sequences)
\end{python}
\subsubsection{多输入和多输出模型}\label{subsec:MIMO}
使用函数式模型的一个典型场景是搭建多输入、多输出的模型。考虑这样一个模型。我们希望预测Twitter上一条新闻会被转发和点赞多少次。模型的主要输入是新闻本身，也就是一个词语的序列。但我们还可以拥有额外的输入，如新闻发布的日期等。这个模型的损失函数将由两部分组成，辅助的损失函数评估仅仅基于新闻本身做出预测的情况，主损失函数评估基于新闻和额外信息的预测的情况，即使来自主损失函数的梯度发生弥散，来自辅助损失函数的信息也能够训练Embeddding和LSTM层。在模型中早点使用主要的损失函数是对于深度网络的一个良好的正则方法。总而言之，该模型框图如\ref{fig:fuc_model}：
\begin{figure}[!htbp]\label{fig:fuc_model}
	\centering
    \includegraphics[width=\textwidth]{multi-input-multi-output-graph}
\end{figure}
让我们用函数式模型来实现这个框图

主要的输入接收新闻本身，即一个整数的序列（每个整数编码了一个词）。这些整数位于1到10，000之间（即我们的字典有10，000个词）。这个序列有100个单词。
\begin{python}
from keras.layers import Input, Embedding, LSTM, Dense
from keras.models import Model

# Headline input: meant to receive sequences of 100 integers, between 1 and 10000.
# Note that we can name any layer by passing it a "name" argument.
main_input = Input(shape=(100,), dtype='int32', name='main_input')

# This embedding layer will encode the input sequence
# into a sequence of dense 512-dimensional vectors.
x = Embedding(output_dim=512, input_dim=10000, input_length=100)(main_input)

# A LSTM will transform the vector sequence into a single vector,
# containing information about the entire sequence
lstm_out = LSTM(32)(x)
\end{python}
然后，我们插入一个额外的损失，使得即使在主损失很高的情况下，LSTM和Embedding层也可以平滑的训练。
\begin{python}
auxiliary_output = Dense(1, activation='sigmoid', name='aux_output')(lstm_out)
\end{python}
再然后，我们将LSTM与额外的输入数据串联起来组成输入，送入模型中：
\begin{python}
auxiliary_input = Input(shape=(5,), name='aux_input')
x = keras.layers.concatenate([lstm_out, auxiliary_input])

# We stack a deep densely-connected network on top
x = Dense(64, activation='relu')(x)
x = Dense(64, activation='relu')(x)
x = Dense(64, activation='relu')(x)

# And finally we add the main logistic regression layer
main_output = Dense(1, activation='sigmoid', name='main_output')(x)
\end{python}
最后，我们定义整个2输入，2输出的模型：
\begin{python}
model = Model(inputs=[main_input, auxiliary_input], outputs=[main_output, auxiliary_output])
\end{python}
模型定义完毕，下一步编译模型。我们给额外的损失赋0.2的权重。我们可以通过关键字参数loss\_weights或loss来为不同的输出设置不同的损失函数或权值。这两个参数均可为Python的列表或字典。这里我们给loss传递单个损失函数，这个损失函数会被应用于所有输出上。
\begin{python}
model.compile(optimizer='rmsprop', loss='binary_crossentropy',
              loss_weights=[1., 0.2])
\end{python}
编译完成后，我们通过传递训练数据和目标值训练该模型：
\begin{python}
model.fit([headline_data, additional_data], [labels, labels],
          epochs=50, batch_size=32)
\end{python}
因为我们输入和输出是被命名过的（在定义时传递了“name”参数），我们也可以用下面的方式编译和训练模型：
\begin{python}
model.compile(optimizer='rmsprop',
              loss={'main_output': 'binary_crossentropy', 'aux_output': 'binary_crossentropy'},
              loss_weights={'main_output': 1., 'aux_output': 0.2})

# And trained it via:
model.fit({'main_input': headline_data, 'aux_input': additional_data},
          {'main_output': labels, 'aux_output': labels},
          epochs=50, batch_size=32)
\end{python}
\subsubsection{共享层}\label{subsec:share}

另一个使用函数式模型的场合是使用共享层的时候。

考虑微博数据，我们希望建立模型来判别两条微博是否是来自同一个用户，这个需求同样可以用来判断一个用户的两条微博的相似性。

一种实现方式是，我们建立一个模型，它分别将两条微博的数据映射到两个特征向量上，然后将特征向量串联并加一个logistic回归层，输出它们来自同一个用户的概率。这种模型的训练数据是一对对的微博。

因为这个问题是对称的，所以处理第一条微博的模型当然也能重用于处理第二条微博。所以这里我们使用一个共享的LSTM层来进行映射。

首先，我们将微博的数据转为（140，256）的矩阵，即每条微博有140个字符，每个单词的特征由一个256维的词向量表示，向量的每个元素为1表示某个字符出现，为0表示不出现，这是一个one-hot编码。

之所以是（140，256）是因为一条微博最多有140个字符，而扩展的ASCII码表编码了常见的256个字符。原文中此处为Twiter，所以对外国人而言这是合理的。如果考虑中文字符，那一个单词的词向量就不止256了。
\begin{python}
import keras
from keras.layers import Input, LSTM, Dense
from keras.models import Model

twiter_a = Input(shape=(140, 256))
twiter_b = Input(shape=(140, 256))
\end{python}
若要对不同的输入共享同一层，就初始化该层一次，然后多次调用它
\begin{python}
# This layer can take as input a matrix
# and will return a vector of size 64
shared_lstm = LSTM(64)

# When we reuse the same layer instance
# multiple times, the weights of the layer
# are also being reused
# (it is effectively *the same* layer)
encoded_a = shared_lstm(tweet_a)
encoded_b = shared_lstm(tweet_b)

# We can then concatenate the two vectors:
merged_vector = keras.layers.concatenate([encoded_a, encoded_b], axis=-1)

# And add a logistic regression on top
predictions = Dense(1, activation='sigmoid')(merged_vector)

# We define a trainable model linking the
# tweet inputs to the predictions
model = Model(inputs=[tweet_a, tweet_b], outputs=predictions)

model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy'])
model.fit([data_a, data_b], labels, epochs=10)
\end{python}
先暂停一下，看看共享层到底输出了什么，它的输出数据shape又是什么

层“节点”的概念

无论何时，当你在某个输入上调用层时，你就创建了一个新的张量（即该层的输出），同时你也在为这个层增加一个“（计算）节点”。这个节点将输入张量映射为输出张量。当你多次调用该层时，这个层就有了多个节点，其下标分别为0，1，2...

在上一版本的Keras中，你可以通过layer.get\_output()方法来获得层的输出张量，或者通过layer.output\_shape获得其输出张量的shape。这个版本的Keras你仍然可以这么做（除了layer.get\_output()被output替换）。但如果一个层与多个输入相连，会出现什么情况呢？

如果层只与一个输入相连，那没有任何困惑的地方。".output"将会返回该层唯一的输出
\begin{python}
a = Input(shape=(140, 256))

lstm = LSTM(32)
encoded_a = lstm(a)

assert lstm.output == encoded_a
\end{python}
但当层与多个输入相连时，会出现问题
\begin{python}
a = Input(shape=(140, 256))
b = Input(shape=(140, 256))

lstm = LSTM(32)
encoded_a = lstm(a)
encoded_b = lstm(b)

lstm.output
\end{python}
上面这段代码会报错
\begin{python}
>> AssertionError: Layer lstm_1 has multiple inbound nodes,
hence the notion of "layer output" is ill-defined.
Use `get_output_at(node_index)` instead.
\end{python}
通过下面这种调用方式即可解决
\begin{python}
assert lstm.get_output_at(0) == encoded_a
assert lstm.get_output_at(1) == encoded_b
\end{python}
对于input\_shape和output\_shape也是一样，如果一个层只有一个节点，或所有的节点都有相同的输入或输出shape，那么input\_shape和output\_shape都是没有歧义的，并也只返回一个值。但是，例如你把一个相同的Conv2D应用于一个大小为(3,32,32)的数据，然后又将其应用于一个(3,64,64)的数据，那么此时该层就具有了多个输入和输出的shape，你就需要显式的指定节点的下标，来表明你想取的是哪个了
\begin{python}
a = Input(shape=(3, 32, 32))
b = Input(shape=(3, 64, 64))
conv = Conv2D(16, (3, 3), padding='same')
conved_a = conv(a)

# Only one input so far, the following will work:
assert conv.input_shape == (None, 3, 32, 32)

conved_b = conv(b)
# now the `.input_shape` property wouldn't work, but this does:
assert conv.get_input_shape_at(0) == (None, 3, 32, 32)
assert conv.get_input_shape_at(1) == (None, 3, 64, 64)
\end{python}
更多的例子

代码示例依然是学习的最佳方式，这里是更多的例子

\subsection{inception模型}

inception的详细结构参见Google的这篇论文：\href{https://arxiv.org/pdf/1409.4842.pdf}{Going Deeper with Convolutions}
\begin{python}
from keras.layers import Conv2D, MaxPooling2D, Input

input_img = Input(shape=(3, 256, 256))

tower_1 = Conv2D(64, (1, 1), padding='same', activation='relu')(input_img)
tower_1 = Conv2D(64, (3, 3), padding='same', activation='relu')(tower_1)

tower_2 = Conv2D(64, (1, 1), padding='same', activation='relu')(input_img)
tower_2 = Conv2D(64, (5, 5), padding='same', activation='relu')(tower_2)

tower_3 = MaxPooling2D((3, 3), strides=(1, 1), padding='same')(input_img)
tower_3 = Conv2D(64, (1, 1), padding='same', activation='relu')(tower_3)

output = keras.layers.concatenate([tower_1, tower_2, tower_3], axis=1)
\end{python}
卷积层的残差连接

残差网络（Residual Network）的详细信息请参考这篇文章：\href{https://arxiv.org/pdf/1512.03385.pdf}{Deep Residual Learning for Image Recognition}
\begin{python}
from keras.layers import Conv2D, Input

# input tensor for a 3-channel 256x256 image
x = Input(shape=(3, 256, 256))
# 3x3 conv with 3 output channels (same as input channels)
y = Conv2D(3, (3, 3), padding='same')(x)
# this returns x + y.
z = keras.layers.add([x, y])
\end{python}
\subsection{共享视觉模型}\label{subsec:共享视觉}

该模型在两个输入上重用了图像处理的模型，用来判别两个MNIST数字是否是相同的数字
\begin{python}
from keras.layers import Conv2D, MaxPooling2D, Input, Dense, Flatten
from keras.models import Model

# First, define the vision modules
digit_input = Input(shape=(1, 27, 27))
x = Conv2D(64, (3, 3))(digit_input)
x = Conv2D(64, (3, 3))(x)
x = MaxPooling2D((2, 2))(x)
out = Flatten()(x)

vision_model = Model(digit_input, out)

# Then define the tell-digits-apart model
digit_a = Input(shape=(1, 27, 27))
digit_b = Input(shape=(1, 27, 27))

# The vision model will be shared, weights and all
out_a = vision_model(digit_a)
out_b = vision_model(digit_b)

concatenated = keras.layers.concatenate([out_a, out_b])
out = Dense(1, activation='sigmoid')(concatenated)

classification_model = Model([digit_a, digit_b], out)
\end{python}
\subsection{视觉问答模型}\label{subsec:视觉问答}

在针对一幅图片使用自然语言进行提问时，该模型能够提供关于该图片的一个单词的答案

这个模型将自然语言的问题和图片分别映射为特征向量，将二者合并后训练一个logistic回归层，从一系列可能的回答中挑选一个。
\begin{python}
from keras.layers import Conv2D, MaxPooling2D, Flatten
from keras.layers import Input, LSTM, Embedding, Dense
from keras.models import Model, Sequential

# First, let's define a vision model using a Sequential model.
# This model will encode an image into a vector.
vision_model = Sequential()
vision_model.add(Conv2D(64, (3, 3) activation='relu', padding='same', input_shape=(3, 224, 224)))
vision_model.add(Conv2D(64, (3, 3), activation='relu'))
vision_model.add(MaxPooling2D((2, 2)))
vision_model.add(Conv2D(128, (3, 3), activation='relu', padding='same'))
vision_model.add(Conv2D(128, (3, 3), activation='relu'))
vision_model.add(MaxPooling2D((2, 2)))
vision_model.add(Conv2D(256, (3, 3), activation='relu', padding='same'))
vision_model.add(Conv2D(256, (3, 3), activation='relu'))
vision_model.add(Conv2D(256, (3, 3), activation='relu'))
vision_model.add(MaxPooling2D((2, 2)))
vision_model.add(Flatten())

# Now let's get a tensor with the output of our vision model:
image_input = Input(shape=(3, 224, 224))
encoded_image = vision_model(image_input)

# Next, let's define a language model to encode the question into a vector.
# Each question will be at most 100 word long,
# and we will index words as integers from 1 to 9999.
question_input = Input(shape=(100,), dtype='int32')
embedded_question = Embedding(input_dim=10000, output_dim=256, input_length=100)(question_input)
encoded_question = LSTM(256)(embedded_question)

# Let's concatenate the question vector and the image vector:
merged = keras.layers.concatenate([encoded_question, encoded_image])

# And let's train a logistic regression over 1000 words on top:
output = Dense(1000, activation='softmax')(merged)

# This is our final model:
vqa_model = Model(inputs=[image_input, question_input], outputs=output)

# The next stage would be training this model on actual data.
\end{python}
\subsection{视频问答模型}\label{视频问答}

在做完图片问答模型后，我们可以快速将其转为视频问答的模型。在适当的训练下，你可以为模型提供一个短视频（如100帧）然后向模型提问一个关于该视频的问题，如“what sport is the boy playing？”->“football”
\begin{python}
from keras.layers import TimeDistributed

video_input = Input(shape=(100, 3, 224, 224))
# This is our video encoded via the previously trained vision_model (weights are reused)
encoded_frame_sequence = TimeDistributed(vision_model)(video_input)  # the output will be a sequence of vectors
encoded_video = LSTM(256)(encoded_frame_sequence)  # the output will be a vector

# This is a model-level representation of the question encoder, reusing the same weights as before:
question_encoder = Model(inputs=question_input, outputs=encoded_question)

# Let's use it to encode the question:
video_question_input = Input(shape=(100,), dtype='int32')
encoded_video_question = question_encoder(video_question_input)

# And this is our video question answering model:
merged = keras.layers.concatenate([encoded_video, encoded_video_question])
output = Dense(1000, activation='softmax')(merged)
video_qa_model = Model(inputs=[video_input, video_question_input], outputs=output)
\end{python}
\chapter{Keras模型}\label{ch:model}
Keras有两种类型的模型，序贯模型（Sequential）和函数式模型（Model），函数式模型应用更为广泛，序贯模型是函数式模型的一种特殊情况。

两类模型有一些方法是相同的：
\begin{itemize}
    \item model.summary()：打印出模型概况
    \item model.get\_config():返回包含模型配置信息的Python字典。模型也可以从它的config信息中重构回去
\end{itemize}
\begin{python}
config = model.get_config()
model = Model.from_config(config)
# or, for Sequential:
model = Sequential.from_config(config)
\end{python}
\begin{itemize}
    \item model.get\_layer()：依据层名或下标获得层对象
    \item model.get\_weights()：返回模型权重张量的列表，类型为numpy array
    \item model.set\_weights()：从numpy array里将权重载入给模型，要求数组具有与model.get\_weights()相同的形状。
    \item model.to\_json：返回代表模型的JSON字符串，仅包含网络结构，不包含权值。可以从JSON字符串中重构原模型：
\begin{python}
from models import model_from_json

json_string = model.to_json()
model = model_from_json(json_string)
\end{python}
\end{itemize}

\begin{itemize}
    \item model.to\_yaml：与model.to\_json类似，同样可以从产生的YAML字符串中重构模型
\end{itemize}
\begin{python}
from models import model_from_yaml

yaml_string = model.to_yaml()
model = model_from_yaml(yaml_string)
\end{python}
示例程序\href{://github.com/bleedingfight/tfnote/blob/article/lstm_predict.py}{载入模型}
\begin{itemize}
    \item model.save\_weights(filepath)：将模型权重保存到指定路径，文件类型是HDF5（后缀是.h5）
    \item model.load\_weights(filepath, by\_name=False)：从HDF5文件中加载权重到当前模型中, 默认情况下模型的结构将保持不变。如果想将权重载入不同的模型（有些层相同）中，则设置by\_name=True，只有名字匹配的层才会载入权重
\end{itemize}
\section{Sequential模型接口}\label{sec:Sequential API}

如果刚开始学习Sequential模型，请首先移步这里\nameref{sec:Sequential}，本节内容是Sequential的API和参数介绍。

常用Sequential属性

model.layers是添加到模型上的层的list
Sequential模型方法

\begin{itemize}
\item add(self, layer)向模型中添加一个层,layer: Layer对象
\item pop(self)弹出模型最后的一层，无返回值
\item compile(self, optimizer, loss, metrics=None, sample\_weight\_mode=None)
编译用来配置模型的学习过程，其参数有
\begin{itemize}
    \item optimizer：字符串（预定义优化器名）或优化器对象，参考\nameref{ch:优化器}
    \item loss：字符串（预定义损失函数名）或目标函数，参考\nameref{ch:obj}
    \item metrics：列表，包含评估模型在训练和测试时的网络性能的指标，典型用法是metrics=['accuracy']
    \item sample\_weight\_mode：如果你需要按时间步为样本赋权（2D权矩阵），将该值设为“temporal”。默认为“None”，代表按样本赋权（1D权）。在下面fit函数的解释中有相关的参考内容。
    \item kwargs：使用TensorFlow作为后端请忽略该参数，若使用Theano作为后端，kwargs的值将会传递给 K.function
\end{itemize}
\begin{python}
model = Sequential()
model.add(Dense(32, input_shape=(500,)))
model.add(Dense(10, activation='softmax'))
model.compile(optimizer='rmsprop',
      loss='categorical_crossentropy',
      metrics=['accuracy'])
\end{python}
模型在使用前必须编译，否则在调用fit或evaluate时会抛出异常。
\item fit
\begin{python}
fit(self, x, y, batch_size=32, epochs=10, verbose=1, callbacks=None, validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None, initial_epoch=0)
\end{python}
本函数将模型训练epochs轮，其参数有：
\begin{itemize}
    \item x：输入数据。如果模型只有一个输入，那么x的类型是numpy array，如果模型有多个输入，那么x的类型应当为list，list的元素是对应于各个输入的numpy array
    \item y：标签，numpy array
    \item batch\_size：整数，指定进行梯度下降时每个batch包含的样本数。训练时一个batch的样本会被计算一次梯度下降，使目标函数优化一步。
    \item epochs：整数，训练的轮数，每个epoch会把训练集轮一遍。
    \item verbose：日志显示，0为不在标准输出流输出日志信息，1为输出进度条记录，2为每个epoch输出一行记录
    \item callbacks：list，其中的元素是keras.callbacks.Callback的对象。这个list中的回调函数将会在训练过程中的适当时机被调用，参考\nameref{ch:callbacks}
    \item validation\_split：0~1之间的浮点数，用来指定训练集的一定比例,数据作为验证集。验证集将不参与训练，并在每个epoch结束后测试的模型的指标，如损失函数、精确度等。注意，validation\_split的划分在shuffle之前，因此如果你的数据本身是有序的，需要先手工打乱再指定validation\_split，否则可能会出现验证集样本不均匀。
    \item validation\_data：形式为（X，y）的tuple，是指定的验证集。此参数将覆盖validation\_spilt。
    \item shuffle：布尔值或字符串，一般为布尔值，表示是否在训练过程中随机打乱输入样本的顺序。若为字符串“batch”，则是用来处理HDF5数据的特殊情况，它将在batch内部将数据打乱。
    \item class\_weight：字典，将不同的类别映射为不同的权值，该参数用来在训练过程中调整损失函数（只能用于训练）
    \item sample\_weight：权值的numpy array，用于在训练时调整损失函数（仅用于训练）。可以传递一个1D的与样本等长的向量用于对样本进行1对1的加权，或者在面对时序数据时，传递一个的形式为（samples，sequence\_length）的矩阵来为每个时间步上的样本赋不同的权。这种情况下请确定在编译模型时添加了sample\_weight\_mode='temporal'。
    \item initial\_epoch: 从该参数指定的epoch开始训练，在继续之前的训练时有用。
fit函数返回一个History的对象，其History.history属性记录了损失函数和其他指标的数值随epoch变化的情况，如果有验证集的话，也包含了验证集的这些指标变化情况
\end{itemize}

\item {evaluate}

\begin{python}
evaluate(self, x, y, batch_size=32, verbose=1, sample_weight=None)
\end{python}
本函数按batch计算在某些输入数据上模型的误差，其参数有：
\begin{itemize}
    \item x：输入数据，与fit一样，是numpy array或numpy array的list
    \item y：标签，numpy array
    \item batch\_size：整数，含义同fit的同名参数
    \item verbose：含义同fit的同名参数，但只能取0或1
    \item sample\_weight：numpy array，含义同fit的同名参数
\end{itemize}
本函数返回一个测试误差的标量值（如果模型没有其他评价指标），或一个标量的list（如果模型还有其他的评价指标）。model.metrics\_names将给出list中各个值的含义。

如果没有特殊说明，以下函数的参数均保持与fit的同名参数相同的含义

如果没有特殊说明，以下函数的verbose参数（如果有）均只能取0或1

\item predict
\begin{python}
predict(self, x, batch_size=32, verbose=0)
\end{python}
本函数按batch获得输入数据对应的输出，其参数有：

函数的返回值是预测值的numpy array

\item train\_on\_batch
\begin{python}
train_on_batch(self, x, y, class_weight=None, sample_weight=None)
\end{python}
本函数在一个batch的数据上进行一次参数更新,函数返回训练误差的标量值或标量值的list，与evaluate的情形相同。

\item test\_on\_batch
\begin{python}
test_on_batch(self, x, y, sample_weight=None)
\end{python}
本函数在一个batch的样本上对模型进行评估,函数的返回与evaluate的情形相同

\item predict\_on\_batch
\begin{python}
predict_on_batch(self, x)
\end{python}
本函数在一个batch的样本上对模型进行测试

函数返回模型在一个batch上的预测结果

\item fit\_generator
\begin{python}
fit_generator(self, generator, steps_per_epoch, epochs=1, verbose=1, callbacks=None, validation_data=None, validation_steps=None, class_weight=None, max_q_size=10, workers=1, pickle_safe=False, initial_epoch=0)
\end{python}
利用Python的生成器，逐个生成数据的batch并进行训练。生成器与模型将并行执行以提高效率。例如，该函数允许我们在CPU上进行实时的数据提升，同时在GPU上进行模型训练

函数的参数是：
\begin{itemize}
    \item generator：生成器函数，生成器的输出应该为：
     \begin{itemize}
        \item 一个形如（inputs，targets）的tuple
        \item 一个形如（inputs, targets,sample\_weight）的tuple。所有的返回值都应该包含相同数目的样本。生成器将无限在数据集上循环。每个epoch以经过模型的样本数达到samples\_per\_epoch时，记一个epoch结束
        \item steps\_per\_epoch：整数，当生成器返回steps\_per\_epoch次数据时计一个epoch结束，执行下一个epoch
    \end{itemize}
\item epochs：整数，数据迭代的轮数
\item verbose：日志显示，0为不在标准输出流输出日志信息，1为输出进度条记录，2为每个epoch输出一行记录
\item validation\_data：具有以下三种形式之一
    \begin{itemize}
    \item 生成验证集的生成器
        \item 一个形如（inputs,targets）的tuple
        \item 一个形如（inputs,targets，sample\_weights）的tuple
    \end{itemize}
\item validation\_steps: 当validation\_data为生成器时，本参数指定验证集的生成器返回次数
\item class\_weight：规定类别权重的字典，将类别映射为权重，常用于处理样本不均衡问题。
\item sample\_weight：权值的numpy array，用于在训练时调整损失函数（仅用于训练）。可以传递一个1D的与样本等长的向量用于对样本进行1对1的加权，或者在面对时序数据时，传递一个的形式为（samples，sequence\_length）的矩阵来为每个时间步上的样本赋不同的权。这种情况下请确定在编译模型时添加了sample\_weight\_mode='temporal'。
\item workers：最大进程数
\item max\_q\_size：生成器队列的最大容量
\item pickle\_safe: 若为真，则使用基于进程的线程。由于该实现依赖多进程，不能传递non picklable（无法被pickle序列化）的参数到生成器中，因为无法轻易将它们传入子进程中。
\item initial\_epoch: 从该参数指定的epoch开始训练，在继续之前的训练时有用。
\end{itemize}
函数返回一个History对象

例子：
\begin{python}
def generate_arrays_from_file(path):
    while 1:
            f = open(path)
            for line in f:
                # create Numpy arrays of input data
                # and labels, from each line in the file
                x, y = process_line(line)
                yield (x, y)
        f.close()

model.fit_generator(generate_arrays_from_file('/my_file.txt'),
        samples_per_epoch=10000, epochs=10)
\end{python}
\item evaluate\_generator
\begin{python}
evaluate_generator(self, generator, steps, max_q_size=10, workers=1, pickle_safe=False)
\end{python}
本函数使用一个生成器作为数据源评估模型，生成器应返回与test\_on\_batch的输入数据相同类型的数据。该函数的参数与fit\_generator同名参数含义相同，steps是生成器要返回数据的轮数。

\item predcit\_generator
\begin{python}
predict_generator(self, generator, steps, max_q_size=10, workers=1, pickle_safe=False, verbose=0)
\end{python}
本函数使用一个生成器作为数据源预测模型，生成器应返回与test\_on\_batch的输入数据相同类型的数据。该函数的参数与fit\_generator同名参数含义相同，steps是生成器要返回数据的轮数。
\end{itemize}
\section{Keras函数式模型API}\label{sec:model api}
Keras的函数式模型为Model，即广义的拥有输入和输出的模型，我们使用Model来初始化一个函数式模型
\begin{python}
from keras.models import Model
from keras.layers import Input, Dense

a = Input(shape=(32,))
b = Dense(32)(a)
model = Model(inputs=a, outputs=b)
\end{python}
在这里，我们的模型以a为输入，以b为输出，同样我们可以构造拥有多输入和多输出的模型
\begin{python}
model = Model(inputs=[a1, a2], outputs=[b1, b3, b3])
\end{python}
常用Model属性
\begin{itemize}
    \item model.layers：组成模型图的各个层
    \item model.inputs：模型的输入张量列表
    \item model.outputs：模型的输出张量列表
\end{itemize}
Model模型方法
\textbf{compile}
\begin{python}
compile(self, optimizer, loss, metrics=None, loss_weights=None, sample_weight_mode=None)
\end{python}
本函数编译模型以供训练，参数有
\begin{itemize}
    \item optimizer：优化器，为预定义优化器名或优化器对象，参考\nameref{ch:优化器}
    \item loss：损失函数，为预定义损失函数名或一个目标函数，参考\nameref{ch:obj}
    \item metrics：列表，包含评估模型在训练和测试时的性能的指标，典型用法是metrics=['accuracy']如果要在多输出模型中为不同的输出指定不同的指标，可像该参数传递一个字典，例如metrics={'ouput\_a': 'accuracy'}
    \item sample\_weight\_mode：如果你需要按时间步为样本赋权（2D权矩阵），将该值设为“temporal”。默认为“None”，代表按样本赋权（1D权）。如果模型有多个输出，可以向该参数传入指定sample\_weight\_mode的字典或列表。在下面fit函数的解释中有相关的参考内容。
    \item kwargs：使用TensorFlow作为后端请忽略该参数，若使用Theano作为后端，kwargs的值将会传递给 K.function
\end{itemize}
当为参数传入非法值时会抛出异常
\begin{remark}
如果你只是载入模型并利用其predict，可以不用进行compile。在Keras中，compile主要完成损失函数和优化器的一些配置，是为训练服务的。predict会在内部进行符号函数的编译工作（通过调用\_make\_predict\_function生成函数），
\end{remark}
\textbf{fit}
\begin{python}
fit(self, x=None, y=None, batch_size=32, epochs=1, verbose=1, callbacks=None, validation_split=0.0, validation_data=None, shuffle=True, class_weight=None, sample_weight=None, initial_epoch=0)
\end{python}
本函数用以训练模型，参数有：
\begin{itemize}
    \item x：输入数据。如果模型只有一个输入，那么x的类型是numpy array，如果模型有多个输入，那么x的类型应当为list，list的元素是对应于各个输入的numpy array。如果模型的每个输入都有名字，则可以传入一个字典，将输入名与其输入数据对应起来。
    \item y：标签，numpy array。如果模型有多个输出，可以传入一个numpy array的list。如果模型的输出拥有名字，则可以传入一个字典，将输出名与其标签对应起来。
batch\_size：整数，指定进行梯度下降时每个batch包含的样本数。训练时一个batch的样本会被计算一次梯度下降，使目标函数优化一步。
    \item nb\_epoch：整数，训练的轮数，训练数据将会被遍历nb\_epoch次。Keras中nb开头的变量均为"number of"的意思
    \item verbose：日志显示，0为不在标准输出流输出日志信息，1为输出进度条记录，2为每个epoch输出一行记录
    \item callbacks：list，其中的元素是keras.callbacks.Callback的对象。这个list中的回调函数将会在训练过程中的适当时机被调用，参考\nameref{ch:callbacks}
validation\_split：0~1之间的浮点数，用来指定训练集的一定比例数据作为验证集。验证集将不参与训练，并在每个epoch结束后测试的模型的指标，如损失函数、精确度等。注意，validation\_split的划分在shuffle之后，因此如果你的数据本身是有序的，需要先手工打乱再指定validation\_split，否则可能会出现验证集样本不均匀。
    \item validation\_data：形式为（X，y）或（X，y，sample\_weights）的tuple，是指定的验证集。此参数将覆盖validation\_spilt。
    \item shuffle：布尔值，表示是否在训练过程中每个epoch前随机打乱输入样本的顺序。
    \item class\_weight：字典，将不同的类别映射为不同的权值，该参数用来在训练过程中调整损失函数（只能用于训练）。该参数在处理非平衡的训练数据（某些类的训练样本数很少）时，可以使得损失函数对样本数不足的数据更加关注。
    \item sample\_weight：权值的numpy array，用于在训练时调整损失函数（仅用于训练）。可以传递一个1D的与样本等长的向量用于对样本进行1对1的加权，或者在面对时序数据时，传递一个形式为（samples，sequence\_length）的矩阵来为每个时间步上的样本赋不同的权。这种情况下请确定在编译模型时添加了sample\_weight\_mode='temporal'。
    \item initial\_epoch: 从该参数指定的epoch开始训练，在继续之前的训练时有用。
输入数据与规定数据不匹配时会抛出错误
\end{itemize}
\begin{quote}
    \emph{fit函数返回一个History的对象，其History.history属性记录了损失函数和其他指标的数值随epoch变化的情况，如果有验证集的话，也包含了验证集的这些指标变化情况}
\end{quote}

\textbf{evaluate}

\begin{python}
evaluate(self, x, y, batch_size=32, verbose=1, sample_weight=None)
\end{python}
本函数按batch计算在某些输入数据上模型的误差，其参数有：
\begin{itemize}
    \item x：输入数据，与fit一样，是numpy array或numpy array的list
    \item y：标签，numpy array
    \item batch\_size：整数，含义同fit的同名参数
    \item verbose：含义同fit的同名参数，但只能取0或1
    \item sample\_weight：numpy array，含义同fit的同名参数
\end{itemize}
本函数返回一个测试误差的标量值（如果模型没有其他评价指标），或一个标量的list（如果模型还有其他的评价指标）。model.metrics\_names将给出list中各个值的含义。

如果没有特殊说明，以下函数的参数均保持与fit的同名参数相同的含义

如果没有特殊说明，以下函数的verbose参数（如果有）均只能取0或1

\textbf{predict}
\begin{python}
predict(self, x, batch_size=32, verbose=0)
\end{python}
本函数按batch获得输入数据对应的输出，其参数有：

函数的返回值是预测值的numpy array

\textbf{train\_on\_batch}
\begin{python}
train_on_batch(self, x, y, class_weight=None, sample_weight=None)
\end{python}
本函数在一个batch的数据上进行一次参数更新

函数返回训练误差的标量值或标量值的list，与evaluate的情形相同。

\textbf{test\_on\_batch}
\begin{python}
test_on_batch(self, x, y, sample_weight=None)
\end{python}
本函数在一个batch的样本上对模型进行评估

函数的返回与evaluate的情形相同

\textbf{predict\_on\_batch}
\begin{python}
predict_on_batch(self, x)
\end{python}
本函数在一个batch的样本上对模型进行测试

函数返回模型在一个batch上的预测结果

\textbf{fit\_generator}
\begin{python}
fit_generator(self, generator, steps_per_epoch, epochs=1, verbose=1, callbacks=None, validation_data=None, validation_steps=None, class_weight=None, max_q_size=10, workers=1, pickle_safe=False, initial_epoch=0)
\end{python}
利用Python的生成器，逐个生成数据的batch并进行训练。生成器与模型将并行执行以提高效率。例如，该函数允许我们在CPU上进行实时的数据提升，同时在GPU上进行模型训练

函数的参数是：
\begin{itemize}
    \item generator：生成器函数，生成器的输出应该为：
        \begin{itemize}
            \item 一个形如（inputs，targets）的tuple
            \item 一个形如（inputs, targets,sample\_weight）的tuple。所有的返回值都应该包含相同数目的样本。生成器将无限在数据集上循环。每个epoch以经过模型的样本数达到samples\_per\_epoch时，记一个epoch结束
        \end{itemize}
    \item steps\_per\_epoch：整数，当生成器返回steps\_per\_epoch次数据时计一个epoch结束，执行下一个epoch
    \item epochs：整数，数据迭代的轮数
    \item verbose：日志显示，0为不在标准输出流输出日志信息，1为输出进度条记录，2为每个epoch输出一行记录
    \item validation\_data：具有以下三种形式之一
    \item
        \begin{itemize}
            \item 生成验证集的生成器
            \item 一个形如（inputs,targets）的tuple
            \item 一个形如（inputs,targets，sample\_weights）的tuple
        \end{itemize}
    \item validation\_steps: 当validation\_data为生成器时，本参数指定验证集的生成器返回次数
    \item class\_weight：规定类别权重的字典，将类别映射为权重，常用于处理样本不均衡问题。
    \item sample\_weight：权值的numpy array，用于在训练时调整损失函数（仅用于训练）。可以传递一个1D的与样本等长的向量用于对样本进行1对1的加权，或者在面对时序数据时，传递一个的形式为（samples，sequence\_length）的矩阵来为每个时间步上的样本赋不同的权。这种情况下请确定在编译模型时添加了sample\_weight\_mode='temporal'。
    \item workers：最大进程数
    \item max\_q\_size：生成器队列的最大容量
    \item pickle\_safe: 若为真，则使用基于进程的线程。由于该实现依赖多进程，不能传递non picklable（无法被pickle序列化）的参数到生成器中，因为无法轻易将它们传入子进程中。
    \item initial\_epoch: 从该参数指定的epoch开始训练，在继续之前的训练时有用。
函数返回一个History对象
\end{itemize}
例子
\begin{python}
def generate_arrays_from_file(path):
    while 1:
        f = open(path)
        for line in f:
        # create numpy arrays of input data
        # and labels, from each line in the file
        x1, x2, y = process_line(line)
        yield ({'input_1': x1, 'input_2': x2}, {'output': y})
        f.close()
    model.fit_generator(generate_arrays_from_file('/my_file.txt'),
                    steps_per_epoch=10000, epochs=10)
                evaluate_generator
                evaluate_generator(self, generator, steps, max_q_size=10, workers=1, pickle_safe=False)
\end{python}
\begin{python}
evaluate_generator(self,generator,steps,max_q_size=10,worker=1,pickle_safe=False)
\end{python}
本函数使用一个生成器作为数据源，来评估模型，生成器应返回与test\_on\_batch的输入数据相同类型的数据。该函数的参数与fit\_generator同名参数含义相同，steps是生成器要返回数据的轮数。
%函数的参数是：
%\begin{itemize}
%    \item generator：生成输入batch数据的生成器
%    \item val\_samples：生成器应该返回的总样本数
%    \item steps：生成器要返回数据的轮数
%    \item max\_q\_size：生成器队列的最大容量
%    \item nb\_worker：使用基于进程的多线程处理时的进程数
%    \item pickle\_safe：若设置为True，则使用基于进程的线程。注意因为它的实现依赖于多进程处理，不可传递不可pickle的参数到生成器中，因为它们不能轻易的传递到子进程中。
%\end{itemize}
\textbf{predict\_generator}
\begin{python}
predict_generator(self, generator, steps, max_q_size=10, workers=1, pickle_safe=False, verbose=0)
\end{python}
本函数使用一个生成器作为数据源预测模型，生成器应返回与test\_on\_batch的输入数据相同类型的数据。该函数的参数与fit\_generator同名参数含义相同，steps是生成器要返回数据的轮数。
函数的参数是：
\begin{itemize}
    \item generator：生成输入batch数据的生成器
    \item val\_samples：生成器应该返回的总样本数
    \item max\_q\_size：生成器队列的最大容量
    \item nb\_worker：使用基于进程的多线程处理时的进程数
    \item pickle\_safe：若设置为True，则使用基于进程的线程。注意因为它的实现依赖于多进程处理，不可传递不可pickle的参数到生成器中，因为它们不能轻易的传递到子进程中。
\end{itemize}
\chapter{网络层}\label{ch:network}
关于Keras的“层”（Layer）,所有的Keras层对象都有如下方法：
\begin{itemize}
    \item layer.get\_weights()：返回层的权重（numpy array）
    \item layer.set\_weights(weights)：从numpy array中将权重加载到该层中，要求numpy array的形状与* layer.get\_weights()的形状相同
    \item layer.get\_config()：返回当前层配置信息的字典，层也可以借由配置信息重构:
\end{itemize}
\begin{python}
layer = Dense(32)
config = layer.get_config()
reconstructed_layer = Dense.from_config(config)
\end{python}
或者：
\begin{python}
from keras import layers

config = layer.get_config()
layer = layers.deserialize({'class_name': layer.__class__.__name__,
                            'config': config})
\end{python}
如果层仅有一个计算节点（即该层不是共享层），则可以通过下列方法获得输入张量、输出张量、输入数据的形状和输出数据的形状：
\begin{itemize}
\item layer.input
\item layer.output
\item layer.input\_shape
\item layer.output\_shape
\end{itemize}
如果该层有多个计算节点（参考\href{http://keras-cn.readthedocs.io/en/latest/getting_started/functional_API/#node}{层计算节点和共享层}）。可以使用下面的方法
\begin{itemize}
\item layer.get\_input\_at(node\_index)
\item layer.get\_output\_at(node\_index)
\item layer.get\_input\_shape\_at(node\_index)
\item layer.get\_output\_shape\_at(node\_index)
\end{itemize}
\section{常用层}\label{sec:common}

常用层对应于core模块，core内部定义了一系列常用的网络层，包括全连接、激活层等

\subsection{Dense层}
\begin{python}
keras.layers.core.Dense(units, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)
\end{python}
Dense就是常用的全连接层，所实现的运算是output = activation(dot(input, kernel)+bias)。其中activation是逐元素计算的激活函数，kernel是本层的权值矩阵，bias为偏置向量，只有当use\_bias=True才会添加。

如果本层的输入数据的维度大于2，则会先被压为与kernel相匹配的大小。

这里是一个使用示例：
\begin{python}
# as first layer in a sequential model:
model = Sequential()
model.add(Dense(32, input_shape=(16,)))
# now the model will take as input arrays of shape (*, 16)
# and output arrays of shape (*, 32)

# after the first layer, you don't need to specify
# the size of the input anymore:
model.add(Dense(32))
\end{python}
参数：
\begin{itemize}
    \item units：大于0的整数，代表该层的输出维度。
    \item activation：激活函数，为预定义的激活函数名（参考\nameref{ch:activation}），或逐元素（element-wise）的Theano函数。如果不指定该参数，将不会使用任何激活函数（即使用线性激活函数：a(x)=x）
    \item use\_bias: 布尔值，是否使用偏置项
    \item kernel\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
    \item bias\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
    \item kernel\_regularizer：施加在权重上的正则项，为Regularizer对象
    \item bias\_regularizer：施加在偏置向量上的正则项，为Regularizer对象
    \item activity\_regularizer：施加在输出上的正则项，为Regularizer对象
    \item kernel\_constraints：施加在权重上的约束项，为Constraints对象
    \item bias\_constraints：施加在偏置上的约束项，为Constraints对象
\end{itemize}
输入

形如(nb\_samples,\ldots, input\_shape[1])的nD张量，最常见的情况为(nb\_samples, input\_dim)的2D张量

输出

形如(nb\_samples, \ldots, units)的nD张量，最常见的情况为(nb\_samples, output\_dim)的2D张量


\subsection{Activation层}


keras.layers.core.Activation(activation)
激活层对一个层的输出施加激活函数

参数
\begin{itemize}
\item activation：将要使用的激活函数，为预定义激活函数名或一个Tensorflow/Theano的函数。参考\nameref{ch:activation}
\end{itemize}
输入shape任意，当使用激活层作为第一层时，要指定input\_shape,输出shape与输入shape相同。
\subsection{Dropout层}
\begin{python}
keras.layers.core.Dropout(rate, noise_shape=None, seed=None)
\end{python}
为输入数据施加Dropout。Dropout将在训练过程中每次更新参数时随机断开一定百分比（rate）的输入神经元，Dropout层用于防止过拟合。

参数
\begin{itemize}
    \item rate：0-1的浮点数，控制需要断开的神经元的比例
    \item noise\_shape：整数张量，为将要应用在输入上的二值Dropout mask的shape，例如你的输入为(batch\_size, timesteps, features)，并且你希望在各个时间步上的Dropout mask都相同，则可传入noise\_shape=(batch\_size, 1, features)。
    \item seed：整数，使用的随机数种子
\end{itemize}
参考\cite{srivastava_dropout:_nodate}

%\href{http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf}{Dropout: A Simple Way to Prevent Neural Networks from Overfitting}
\subsection{Flatten层}

keras.layers.core.Flatten():
Flatten层用来将输入“压平”，即把多维的输入一维化，常用在从卷积层到全连接层的过渡。Flatten不影响batch的大小。

例子
\begin{python}
model = Sequential()
model.add(Convolution2D(64, 3, 3,
            border_mode='same',
            input_shape=(3, 32, 32)))
# now: model.output_shape == (None, 64, 32, 32)

model.add(Flatten())
# now: model.output_shape == (None, 65536)
\end{python}
\subsection{Reshape层}
\begin{python}
keras.layers.core.Reshape(target_shape)
\end{python}
Reshape层用来将输入shape转换为特定的shape

参数
\begin{itemize}
    \item target\_shape：目标shape，为整数的tuple，不包含样本数目的维度（batch大小）
\end{itemize}
输入shape任意，但输入的shape必须固定。当使用该层为模型首层时，需要指定input\_shape参数。

输出shape

(batch\_size,)+target\_shape

例子
\begin{python}
# as first layer in a Sequential model
model = Sequential()
model.add(Reshape((3, 4), input_shape=(12,)))
# now: model.output_shape == (None, 3, 4)
# note: `None` is the batch dimension

# as intermediate layer in a Sequential model
model.add(Reshape((6, 2)))
# now: model.output_shape == (None, 6, 2)

# also supports shape inference using `-1` as dimension
model.add(Reshape((-1, 2, 2)))
# now: model.output_shape == (None, 3, 2, 2)
\end{python}
\subsection{Permute层}
\begin{python}
keras.layers.core.Permute(dims)
\end{python}
Permute层将输入的维度按照给定模式进行重排，例如，当需要将RNN和CNN网络连接时，可能会用到该层。

参数
\begin{itemize}
    \item dims：整数tuple，指定重排的模式，不包含样本数的维度。重排模式的下标从1开始。例如（2，1）代表将输入的第二个维度重排到输出的第一个维度，而将输入的第一个维度重排到第二个维度
例子
\end{itemize}
\begin{python}
model = Sequential()
model.add(Permute((2, 1), input_shape=(10, 64)))
# now: model.output_shape == (None, 64, 10)
# note: `None` is the batch dimension
\end{python}
输入shape任意，当使用激活层作为第一层时，要指定input\_shape\newline
输出shape与输入相同，但是其维度按照指定的模式重新排列

\subsection{RepeatVector层}
\begin{python}
keras.layers.core.RepeatVector(n)
\end{python}
参数
\begin{itemize}
    \item n：整数，重复的次数
\end{itemize}
输入shape形如（nb\_samples, features）的2D张量\newline
输出shape形如（nb\_samples, n, features）的3D张量

例子
\begin{python}
model = Sequential()
model.add(Dense(32, input_dim=32))
# now: model.output_shape == (None, 32)
# note: `None` is the batch dimension

model.add(RepeatVector(3))
# now: model.output_shape == (None, 3, 32)
\end{python}
\subsection{Lambda层}
\begin{python}
keras.layers.core.Lambda(function, output_shape=None, mask=None, arguments=None)
\end{python}
本函数用以对上一层的输出施以任何Theano/TensorFlow表达式

参数
\begin{itemize}
    \item function：要实现的函数，该函数仅接受一个变量，即上一层的输出
    \item output\_shape：函数应该返回的值的shape，可以是一个tuple，也可以是一个根据输入shape计算输出shape的函数
    \item mask: 掩膜
    \item arguments：可选，字典，用来记录向函数中传递的其它关键字参数
\end{itemize}
例子
\begin{python}
# add a x -> x^2 layer
model.add(Lambda(lambda x: x ** 2))
# add a layer that returns the concatenation
# of the positive part of the input and
# the opposite of the negative part

def antirectifier(x):
    x -= K.mean(x, axis=1, keepdims=True)
    x = K.l2_normalize(x, axis=1)
    pos = K.relu(x)
    neg = K.relu(-x)
    return K.concatenate([pos, neg], axis=1)

def antirectifier_output_shape(input_shape):
    shape = list(input_shape)
    assert len(shape) == 2  # only valid for 2D tensors
    shape[-1] *= 2
    return tuple(shape)

model.add(Lambda(antirectifier,
         output_shape=antirectifier_output_shape))
\end{python}
输入shape任意，当使用该层作为第一层时，要指定input\_shape\newline
输出shape由output\_shape参数指定的输出shape，当使用tensorflow时可自动推断

\subsection{ActivityRegularizer层}
\begin{python}
keras.layers.core.ActivityRegularization(l1=0.0, l2=0.0)
\end{python}
经过本层的数据不会有任何变化，但会基于其激活值更新损失函数值

参数
\begin{itemize}
    \item l1：1范数正则因子（正浮点数）
    \item l2：2范数正则因子（正浮点数）
\end{itemize}
输入shape任意，当使用该层作为第一层时，要指定input\_shape\newline
输出shape与输入shape相同

\subsection{Masking层}
\begin{python}
keras.layers.core.Masking(mask_value=0.0)
\end{python}
使用给定的值对输入的序列信号进行“屏蔽”，用以定位需要跳过的时间步

对于输入张量的时间步，即输入张量的第1维度（维度从0开始算，见例子），如果输入张量在该时间步上都等于mask\_value，则该时间步将在模型接下来的所有层（只要支持masking）被跳过（屏蔽）。

如果模型接下来的一些层不支持masking，却接受到masking过的数据，则抛出异常。

例子

考虑输入数据x是一个形如(samples,timesteps,features)的张量，现将其送入LSTM层。因为你缺少时间步为3和5的信号，所以你希望将其掩盖。这时候应该：

赋值x[:,3,:] = 0.，x[:,5,:] = 0.
在LSTM层之前插入mask\_value=0.的Masking层
\begin{itemize}
    \item model = Sequential()
    \item model.add(Masking(mask\_value=0., input\_shape=(timesteps, features)))
model.add(LSTM(32))
\end{itemize}
\section{卷积层}

\subsection{Conv1D层}
\begin{python}
keras.layers.convolutional.Conv1D(filters, kernel_size, strides=1, padding='valid', dilation_rate=1, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)
\end{python}
一维卷积层（即时域卷积），用以在一维输入信号上进行邻域滤波。当使用该层作为首层时，需要提供关键字参数input\_shape。例如(10,128)代表一个长为10的序列，序列中每个信号为128向量。而(None, 128)代表变长的128维向量序列。

该层生成将输入信号与卷积核按照单一的空域（或时域）方向进行卷积。如果use\_bias=True，则还会加上一个偏置项，若activation不为None，则输出为经过激活函数的输出。

参数
\begin{itemize}
\item filters：卷积核的数目（即输出的维度）
\item kernel\_size：整数或由单个整数构成的list/tuple，卷积核的空域或时域窗长度
strides：整数或由单个整数构成的list/tuple，为卷积的步长。任何不为1的strides均与任何不为1的dilation\_rata均不兼容
\item padding：补0策略，为“valid”, “same” 或“causal”，“causal”将产生因果（膨胀的）卷积，即output[t]不依赖于input[t+1：]。当对不能违反时间顺序的时序信号建模时有用。参考WaveNet: A Generative Model for Raw Audio, section 2.1.。“valid”代表只进行有效的卷积，即对边界数据不处理。“same”代表保留边界处的卷积结果，通常会导致输出shape与输入shape相同。
\item activation：激活函数，为预定义的激活函数名（参考\nameref{ch:activation}），或逐元素（element-wise）的Theano函数。如果不指定该参数，将不会使用任何激活函数（即使用线性激活函数：a(x)=x）
\item dilation\_rate：整数或由单个整数构成的list/tuple，指定dilated convolution中的膨胀比例。任何不为1的dilation\_rata均与任何不为1的strides均不兼容。
\item use\_bias:布尔值，是否使用偏置项
\item kernel\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item bias\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item kernel\_regularizer：施加在权重上的正则项，为Regularizer对象
\item bias\_regularizer：施加在偏置向量上的正则项，为Regularizer对象
\item activity\_regularizer：施加在输出上的正则项，为Regularizer对象
\item kernel\_constraints：施加在权重上的约束项，为Constraints对象
\item bias\_constraints：施加在偏置上的约束项，为Constraints对象
\end{itemize}
输入shape

形如（samples，steps，input\_dim）的3D张量

输出shape

形如（samples，new\_steps，nb\_filter）的3D张量，因为有向量填充的原因，steps的值会改变
\begin{remark}
可以将Convolution1D看作Convolution2D的快捷版，对例子中（10，32）的信号进行1D卷积相当于对其进行卷积核为（filter\_length, 32）的2D卷积。
\end{remark}

\subsection{Conv2D层}
\begin{python}
keras.layers.convolutional.Conv2D(filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, dilation_rate=(1, 1), activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)
\end{python}
二维卷积层，即对图像的空域卷积。该层对二维输入进行滑动窗卷积，当使用该层作为第一层时，应提供input\_shape参数。例如input\_shape = (128,128,3)代表128*128的彩色RGB图像（data\_format='channels\_last'）
参数
\begin{itemize}
\item filters：卷积核的数目（即输出的维度）
\item kernel\_size：单个整数或由两个整数构成的list/tuple，卷积核的宽度和长度。如为单个整数，则表示在各个空间维度的相同长度。
\item strides：单个整数或由两个整数构成的list/tuple，为卷积的步长。如为单个整数，则表示在各个空间维度的相同步长。任何不为1的strides均与任何不为1的dilation\_rata均不兼容
\item padding：补0策略，为“valid”, “same” 。“valid”代表只进行有效的卷积，即对边界数据不处理。“same”代表保留边界处的卷积结果，通常会导致输出shape与输入shape相同。
\item activation：激活函数，为预定义的激活函数名（参考\nameref{ch:activation}），或逐元素（element-wise）的Theano函数。如果不指定该参数，将不会使用任何激活函数（即使用线性激活函数：a(x)=x）
\item dilation\_rate：单个整数或由两个个整数构成的list/tuple，指定dilated convolution中的膨胀比例。任何不为1的dilation\_rata均与任何不为1的strides均不兼容。
\item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表图像的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128的RGB图像为例，“channels\_first”应将数据组织为（3,128,128），而“channels\_last”应将数据组织为（128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\item use\_bias:布尔值，是否使用偏置项
\item kernel\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item bias\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item kernel\_regularizer：施加在权重上的正则项，为Regularizer对象
\item bias\_regularizer：施加在偏置向量上的正则项，为Regularizer对象
\item activity\_regularizer：施加在输出上的正则项，为Regularizer对象
\item kernel\_constraints：施加在权重上的约束项，为Constraints对象
\item bias\_constraints：施加在偏置上的约束项，为Constraints对象
\end{itemize}
输入shape
‘channels\_first’模式下，输入形如（samples,channels，rows，cols）的4D张量
‘channels\_last’模式下，输入形如（samples，rows，cols，channels）的4D张量

注意这里的输入shape指的是函数内部实现的输入shape，而非函数接口应指定的input\_shape，请参考下面提供的例子。

输出shape

‘channels\_first’模式下，为形如（samples，nb\_filter, new\_rows, new\_cols）的4D张量

‘channels\_last’模式下，为形如（samples，new\_rows, new\_cols，nb\_filter）的4D张量

输出的行列数可能会因为填充方法而改变

\subsection{SeparableConv2D层}
\begin{python}
keras.layers.convolutional.SeparableConv2D(filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, depth_multiplier=1, activation=None, use_bias=True, depthwise_initializer='glorot_uniform', pointwise_initializer='glorot_uniform', bias_initializer='zeros', depthwise_regularizer=None, pointwise_regularizer=None, bias_regularizer=None, activity_regularizer=None, depthwise_constraint=None, pointwise_constraint=None, bias_constraint=None)
\end{python}
该层是在深度方向上的可分离卷积。

可分离卷积首先按深度方向进行卷积（对每个输入通道分别卷积），然后逐点进行卷积，将上一步的卷积结果混合到输出通道中。参数depth\_multiplier控制了在depthwise卷积（第一步）的过程中，每个输入通道信号产生多少个输出通道。

直观来说，可分离卷积可以看做讲一个卷积核分解为两个小的卷积核，或看作Inception模块的一种极端情况。

当使用该层作为第一层时，应提供input\_shape参数。例如input\_shape = (3,128,128)代表128*128的彩色RGB图像

参数
\begin{itemize}
\item filters：卷积核的数目（即输出的维度）
\item kernel\_size：单个整数或由两个个整数构成的list/tuple，卷积核的宽度和长度。如为单个整数，则表示在各个空间维度的相同长度。
\item strides：单个整数或由两个整数构成的list/tuple，为卷积的步长。如为单个整数，则表示在各个空间维度的相同步长。任何不为1的strides均与任何不为1的dilation\_rata均不兼容
\item padding：补0策略，为“valid”, “same” 。“valid”代表只进行有效的卷积，即对边界数据不处理。“same”代表保留边界处的卷积结果，通常会导致输出shape与输入shape相同。
\item activation：激活函数，为预定义的激活函数名（参考\nameref{ch:activation}），或逐元素（element-wise）的Theano函数。如果不指定该参数，将不会使用任何激活函数（即使用线性激活函数：a(x)=x）
\item dilation\_rate：单个整数或由两个个整数构成的list/tuple，指定dilated convolution中的膨胀比例。任何不为1的dilation\_rata均与任何不为1的strides均不兼容。
\item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表图像的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128的RGB图像为例，“channels\_first”应将数据组织为（3,128,128），而“channels\_last”应将数据组织为（128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\item use\_bias:布尔值，是否使用偏置项
\item depth\_multiplier：在按深度卷积的步骤中，每个输入通道使用多少个输出通道
\item kernel\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item bias\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item depthwise\_regularizer：施加在按深度卷积的权重上的正则项，为Regularizer对象
\item pointwise\_regularizer：施加在按点卷积的权重上的正则项，为Regularizer对象
\item kernel\_regularizer：施加在权重上的正则项，为Regularizer对象
\item bias\_regularizer：施加在偏置向量上的正则项，为Regularizer对象
\item activity\_regularizer：施加在输出上的正则项，为Regularizer对象
\item kernel\_constraints：施加在权重上的约束项，为Constraints对象
\item bias\_constraints：施加在偏置上的约束项，为Constraints对象
\item depthwise\_constraint：施加在按深度卷积权重上的约束项，为Constraints对象
\item pointwise\_constraint施加在按点卷积权重的约束项，为Constraints对象
\item \end{itemize}
输入shape

‘channels\_first’模式下，输入形如（samples,channels，rows，cols）的4D张量

‘channels\_last’模式下，输入形如（samples，rows，cols，channels）的4D张量

注意这里的输入shape指的是函数内部实现的输入shape，而非函数接口应指定的input\_shape，请参考下面提供的例子。

输出shape

‘channels\_first’模式下，为形如（samples，nb\_filter, new\_rows, new\_cols）的4D张量

‘channels\_last’模式下，为形如（samples，new\_rows, new\_cols，nb\_filter）的4D张量

输出的行列数可能会因为填充方法而改变

\subsection{Conv2DTranspose层}
\begin{python}
keras.layers.convolutional.Conv2DTranspose(filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)
\end{python}
该层是转置的卷积操作（反卷积）。需要反卷积的情况通常发生在用户想要对一个普通卷积的结果做反方向的变换。例如，将具有该卷积层输出shape的tensor转换为具有该卷积层输入shape的tensor。同时保留与卷积层兼容的连接模式。

当使用该层作为第一层时，应提供input\_shape参数。例如input\_shape = (3,128,128)代表128*128的彩色RGB图像

参数
\begin{itemize}
    \item filters：卷积核的数目（即输出的维度）
    \item kernel\_size：单个整数或由两个个整数构成的list/tuple，卷积核的宽度和长度。如为单个整数，则表示在各个空间维度的相同长度。
    \item strides：单个整数或由两个整数构成的list/tuple，为卷积的步长。如为单个整数，则表示在各个空间维度的相同步长。任何不为1的strides均与任何不为1的dilation\_rata均不兼容
    \item padding：补0策略，为“valid”, “same” 。“valid”代表只进行有效的卷积，即对边界数据不处理。“same”代表保留边界处的卷积结果，通常会导致输出shape与输入shape相同。
    \item activation：激活函数，为预定义的激活函数名（参考\nameref{ch:activation}），或逐元素（element-wise）的Theano函数。如果不指定该参数，将不会使用任何激活函数（即使用线性激活函数：a(x)=x）
    \item dilation\_rate：单个整数或由两个个整数构成的list/tuple，指定dilated convolution中的膨胀比例。任何不为1的dilation\_rata均与任何不为1的strides均不兼容。
    \item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表图像的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128的RGB图像为例，“channels\_first”应将数据组织为（3,128,128），而“channels\_last”应将数据组织为（128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
    \item use\_bias:布尔值，是否使用偏置项
    \item kernel\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
    \item bias\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
    \item kernel\_regularizer：施加在权重上的正则项，为Regularizer对象
    \item bias\_regularizer：施加在偏置向量上的正则项，为Regularizer对象
    \item activity\_regularizer：施加在输出上的正则项，为Regularizer对象
    \item kernel\_constraints：施加在权重上的约束项，为Constraints对象
    \item bias\_constraints：施加在偏置上的约束项，为Constraints对象
\item \end{itemize}
输入shape

‘channels\_first’模式下，输入形如（samples,channels，rows，cols）的4D张量

‘channels\_last’模式下，输入形如（samples，rows，cols，channels）的4D张量

注意这里的输入shape指的是函数内部实现的输入shape，而非函数接口应指定的input\_shape，请参考下面提供的例子。

输出shape

‘channels\_first’模式下，为形如（samples，nb\_filter, new\_rows, new\_cols）的4D张量

‘channels\_last’模式下，为形如（samples，new\_rows, new\_cols，nb\_filter）的4D张量

输出的行列数可能会因为填充方法而改变

参考文献
\begin{itemize}
    \item \href{https://arxiv.org/pdf/1603.07285.pdf}{A guide to convolution arithmetic for deep learning}
    \item \href{http://deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html#transposed-convolution-arithmetic}{Transposed convolution arithmetic}
    \item \href{http://www.matthewzeiler.com/wp-content/uploads/2017/07/cvpr2010.pdf}{Deconvolutional Networks}
\end{itemize}
\subsection{Conv3D层}
\begin{python}
keras.layers.convolutional.Conv3D(filters, kernel_size, strides=(1, 1, 1), padding='valid', data_format=None, dilation_rate=(1, 1, 1), activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)
\end{python}
三维卷积对三维的输入进行滑动窗卷积，当使用该层作为第一层时，应提供input\_shape参数。例如input\_shape = (3,10,128,128)代表对10帧128*128的彩色RGB图像进行卷积。数据的通道位置仍然有data\_format参数指定。

参数
\begin{itemize}
    \item filters：卷积核的数目（即输出的维度）
    \item kernel\_size：单个整数或由3个整数构成的list/tuple，卷积核的宽度和长度。如为单个整数，则表示在各个空间维度的相同长度。
    \item strides：单个整数或由3个整数构成的list/tuple，为卷积的步长。如为单个整数，则表示在各个空间维度的相同步长。任何不为1的strides均与任何不为1的dilation\_rata均不兼容
    \item padding：补0策略，为“valid”, “same” 。“valid”代表只进行有效的卷积，即对边界数据不处理。“same”代表保留边界处的卷积结果，通常会导致输出shape与输入shape相同。
    \item activation：激活函数，为预定义的激活函数名（参考\nameref{ch:activation}），或逐元素（element-wise）的Theano函数。如果不指定该参数，将不会使用任何激活函数（即使用线性激活函数：a(x)=x）
    \item dilation\_rate：单个整数或由3个个整数构成的list/tuple，指定dilated convolution中的膨胀比例。任何不为1的dilation\_rata均与任何不为1的strides均不兼容。
    \item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表数据的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128x128的数据为例，“channels\_first”应将数据组织为（3,128,128,128），而“channels\_last”应将数据组织为（128,128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
    \item use\_bias:布尔值，是否使用偏置项
    \item kernel\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
    \item bias\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
    \item kernel\_regularizer：施加在权重上的正则项，为Regularizer对象
    \item bias\_regularizer：施加在偏置向量上的正则项，为Regularizer对象
    \item activity\_regularizer：施加在输出上的正则项，为Regularizer对象
    \item kernel\_constraints：施加在权重上的约束项，为Constraints对象
    \item bias\_constraints：施加在偏置上的约束项，为Constraints对象
\end{itemize}
输入shape

‘channels\_first’模式下，输入应为形如（samples，channels，input\_dim1，input\_dim2, input\_dim3）的5D张量

‘channels\_last’模式下，输入应为形如（samples，input\_dim1，input\_dim2, input\_dim3，channels）的5D张量

这里的输入shape指的是函数内部实现的输入shape，而非函数接口应指定的input\_shape。

\subsection{Cropping1D层}
\begin{itemize}
    \item keras.layers.convolutional.Cropping1D(cropping=(1, 1))
\end{itemize}
在时间轴（axis1）上对1D输入（即时间序列）进行裁剪

参数
\begin{itemize}
\item cropping：长为2的tuple，指定在序列的首尾要裁剪掉多少个元素
\end{itemize}
输入shape

形如（samples，axis\_to\_crop，features）的3D张量
输出shape

形如（samples，cropped\_axis，features）的3D张量
Cropping2D层

keras.layers.convolutional.Cropping2D(cropping=((0, 0), (0, 0)), data\_format=None)
对2D输入（图像）进行裁剪，将在空域维度，即宽和高的方向上裁剪

参数
\begin{itemize}
\item cropping：长为2的整数tuple，分别为宽和高方向上头部与尾部需要裁剪掉的元素数
data\_format：字符串，“channels\_first”或“channels\_last”之一，代表图像的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128的RGB图像为例，“channels\_first”应将数据组织为（3,128,128），而“channels\_last”应将数据组织为（128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\end{itemize}
输入shape

形如（samples，depth, first\_axis\_to\_crop, second\_axis\_to\_crop）

输出shape

形如(samples, depth, first\_cropped\_axis, second\_cropped\_axis)的4D张量

\subsection{Cropping3D层}
\begin{itemize}
\item keras.layers.convolutional.Cropping3D(cropping=((1, 1), (1, 1), (1, 1)), data\_format=None)
\end{itemize}
对2D输入（图像）进行裁剪

参数
\begin{itemize}
    \item cropping：长为3的整数tuple，分别为三个方向上头部与尾部需要裁剪掉的元素数
data\_format：字符串，“channels\_first”或“channels\_last”之一，代表数据的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128x128的数据为例，“channels\_first”应将数据组织为（3,128,128,128），而“channels\_last”应将数据组织为（128,128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\end{itemize}
输入shape

形如 (samples, depth, first\_axis\_to\_crop, second\_axis\_to\_crop, third\_axis\_to\_crop)的5D张量

输出shape

形如(samples, depth, first\_cropped\_axis, second\_cropped\_axis, third\_cropped\_axis)的5D张量

\subsection{UpSampling1D层}
\begin{python}
keras.layers.convolutional.UpSampling1D(size=2)
\end{python}
在时间轴上，将每个时间步重复length次

参数
\begin{itemize}
    \item size：上采样因子
\end{itemize}
输入shape

形如（samples，steps，features）的3D张量
输出shape

形如（samples，upsampled\_steps，features）的3D张量
UpSampling2D层

keras.layers.convolutional.UpSampling2D(size=(2, 2), data\_format=None)
将数据的行和列分别重复size[0]和size[1]次

参数
\begin{itemize}
\item size：整数tuple，分别为行和列上采样因子
\item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表图像的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128的RGB图像为例，“channels\_first”应将数据组织为（3,128,128），而“channels\_last”应将数据组织为（128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\end{itemize}
输入shape

‘channels\_first’模式下，为形如（samples，channels, rows，cols）的4D张量

‘channels\_last’模式下，为形如（samples，rows, cols，channels）的4D张量

输出shape

‘channels\_first’模式下，为形如（samples，channels, upsampled\_rows, upsampled\_cols）的4D张量

‘channels\_last’模式下，为形如（samples，upsampled\_rows, upsampled\_cols，channels）的4D张量

UpSampling3D层
\begin{python}
keras.layers.convolutional.UpSampling3D(size=(2, 2, 2), data_format=None)
\end{python}
将数据的三个维度上分别重复size[0]、size[1]和ize[2]次

本层目前只能在使用Theano为后端时可用

参数
\begin{itemize}
\item size：长为3的整数tuple，代表在三个维度上的上采样因子
\item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表数据的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128x128的数据为例，“channels\_first”应将数据组织为（3,128,128,128），而“channels\_last”应将数据组织为（128,128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\end{itemize}
输入shape

‘channels\_first’模式下，为形如（samples, channels, len\_pool\_dim1, len\_pool\_dim2, len\_pool\_dim3）的5D张量

‘channels\_last’模式下，为形如（samples, len\_pool\_dim1, len\_pool\_dim2, len\_pool\_dim3，channels, ）的5D张量

输出shape

‘channels\_first’模式下，为形如（samples, channels, dim1, dim2, dim3）的5D张量

‘channels\_last’模式下，为形如（samples, upsampled\_dim1, upsampled\_dim2, upsampled\_dim3,channels,）的5D张量

\subsection{ZeroPadding1D层}
\begin{itemize}
    \item keras.layers.convolutional.ZeroPadding1D(padding=1)
\end{itemize}
对1D输入的首尾端（如时域序列）填充0，以控制卷积以后向量的长度

参数
\begin{itemize}
\item padding：整数，表示在要填充的轴的起始和结束处填充0的数目，这里要填充的轴是轴1（第1维，第0维是样本数）
\end{itemize}
输入shape

形如（samples，axis\_to\_pad，features）的3D张量

输出shape

形如（samples，paded\_axis，features）的3D张量

\subsection{ZeroPadding2D层}
\begin{python}
keras.layers.convolutional.ZeroPadding2D(padding=(1, 1), data_format=None)
\end{python}
对2D输入（如图片）的边界填充0，以控制卷积以后特征图的大小

参数
\begin{itemize}
    \item padding：整数tuple，表示在要填充的轴的起始和结束处填充0的数目，这里要填充的轴是轴3和轴4（即在'th'模式下图像的行和列，在‘channels\_last’模式下要填充的则是轴2，3）
data\_format：字符串，“channels\_first”或“channels\_last”之一，代表图像的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128的RGB图像为例，“channels\_first”应将数据组织为（3,128,128），而“channels\_last”应将数据组织为（128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\end{itemize}
输入shape

‘channels\_first’模式下，形如（samples，channels，first\_axis\_to\_pad，second\_axis\_to\_pad）的4D张量

‘channels\_last’模式下，形如（samples，first\_axis\_to\_pad，second\_axis\_to\_pad, channels）的4D张量

输出shape

‘channels\_first’模式下，形如（samples，channels，first\_paded\_axis，second\_paded\_axis）的4D张量

‘channels\_last’模式下，形如（samples，first\_paded\_axis，second\_paded\_axis, channels）的4D张量

\subsection{ZeroPadding3D层}
\begin{itemize}
    \item keras.layers.convolutional.ZeroPadding3D(padding=(1, 1, 1), data\_format=None)
\end{itemize}
将数据的三个维度上填充0

本层目前只能在使用Theano为后端时可用

参数
\begin{itemize}
    \item padding：整数tuple，表示在要填充的轴的起始和结束处填充0的数目，这里要填充的轴是轴3，轴4和轴5，‘channels\_last’模式下则是轴2，3和4

    \item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表数据的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128x128的数据为例，“channels\_first”应将数据组织为（3,128,128,128），而“channels\_last”应将数据组织为（128,128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\end{itemize}
输入shape

‘channels\_first’模式下，为形如（samples, channels, first\_axis\_to\_pad，first\_axis\_to\_pad, first\_axis\_to\_pad,）的5D张量

‘channels\_last’模式下，为形如（samples, first\_axis\_to\_pad，first\_axis\_to\_pad, first\_axis\_to\_pad, channels）的5D张量

输出shape

‘channels\_first’模式下，为形如（samples, channels, first\_paded\_axis，second\_paded\_axis, third\_paded\_axis,）的5D张量

‘channels\_last’模式下，为形如（samples, len\_pool\_dim1, len\_pool\_dim2, len\_pool\_dim3，channels, ）的5D张量

\section{池化层}

\subsection{MaxPooling1D层}
\begin{python}
keras.layers.pooling.MaxPooling1D(pool_size=2, strides=None, padding='valid')
\end{python}
对时域1D信号进行最大值池化

参数
\begin{itemize}
    \item pool\_size：整数，池化窗口大小
    \item strides：整数或None，下采样因子，例如设2将会使得输出shape为输入的一半，若为None则默认值为pool\_size。
    \item padding：‘valid’或者‘same’
\end{itemize}
输入shape

形如（samples，steps，features）的3D张量
输出shape

形如（samples，downsampled\_steps，features）的3D张量
\subsection{MaxPooling2D层}
\begin{python}
keras.layers.pooling.MaxPooling2D(pool_size=(2, 2), strides=None, padding='valid', data_format=None)
\end{python}
为空域信号施加最大值池化

参数
\begin{itemize}
    \item pool\_size：整数或长为2的整数tuple，代表在两个方向（竖直，水平）上的下采样因子，如取（2，2）将使图片在两个维度上均变为原长的一半。为整数意为各个维度值相同且为该数字。
    \item strides：整数或长为2的整数tuple，或者None，步长值。
    \item padding：‘valid’或者‘same’
    \item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表图像的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128的RGB图像为例，“channels\_first”应将数据组织为（3,128,128），而“channels\_last”应将数据组织为（128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\end{itemize}
输入数据的shape
\begin{itemize}
\item ‘channels\_first’模式下，为形如（samples，channels, rows，cols）的4D张量
\item ‘channels\_last’模式下，为形如（samples，rows, cols，channels）的4D张量
\end{itemize}
输出shape
\begin{itemize}
\item ‘channels\_first’模式下，为形如（samples，channels, pooled\_rows, pooled\_cols）的4D张量:
\item ‘channels\_last’模式下，为形如（samples，pooled\_rows, pooled\_cols，channels）的4D张量
\end{itemize}
\subsection{MaxPooling3D层}
\begin{python}
keras.layers.pooling.MaxPooling3D(pool_size=(2, 2, 2), strides=None, padding='valid', data_format=None)
\end{python}
为3D信号（空域或时空域）施加最大值池化

本层目前只能在使用Theano为后端时可用

参数
\begin{itemize}
\item pool\_size：整数或长为3的整数tuple，代表在三个维度上的下采样因子，如取（2，2，2）将使信号在每个维度都变为原来的一半长。
\item strides：整数或长为3的整数tuple，或者None，步长值。
\item padding：‘valid’或者‘same’
\item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表数据的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128x128的数据为例，“channels\_first”应将数据组织为（3,128,128,128），而“channels\_last”应将数据组织为（128,128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\end{itemize}
输入shape

‘channels\_first’模式下，为形如（samples, channels, len\_pool\_dim1, len\_pool\_dim2, len\_pool\_dim3）的5D张量

‘channels\_last’模式下，为形如（samples, len\_pool\_dim1, len\_pool\_dim2, len\_pool\_dim3，channels, ）的5D张量

输出shape

‘channels\_first’模式下，为形如（samples, channels, pooled\_dim1, pooled\_dim2, pooled\_dim3）的5D张量

‘channels\_last’模式下，为形如（samples, pooled\_dim1, pooled\_dim2, pooled\_dim3,channels,）的5D张量

\subsection{AveragePooling1D层}
\begin{itemize}
    \item keras.layers.pooling.AveragePooling1D(pool\_size=2, strides=None, padding='valid')
\end{itemize}
对时域1D信号进行平均值池化

参数
\begin{itemize}
    \item pool\_size：整数，池化窗口大小
    \item strides：整数或None，下采样因子，例如设2将会使得输出shape为输入的一半，若为None则默认值为pool\_size。
    \item padding：‘valid’或者‘same’
\end{itemize}
输入shape

形如（samples，steps，features）的3D张量
输出shape

形如（samples，downsampled\_steps，features）的3D张量
\subsection{AveragePooling2D层}
\begin{python}
keras.layers.pooling.AveragePooling2D(pool_size=(2, 2), strides=None, padding='valid', data_format=None)
\end{python}
为空域信号施加平均值池化

参数
\begin{itemize}
\item pool\_size：整数或长为2的整数tuple，代表在两个方向（竖直，水平）上的下采样因子，如取（2，2）将使图片在两个维度上均变为原长的一半。为整数意为各个维度值相同且为该数字。
\item strides：整数或长为2的整数tuple，或者None，步长值。
\item border\_mode：‘valid’或者‘same’
\item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表图像的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128的RGB图像为例，“channels\_first”应将数据组织为（3,128,128），而“channels\_last”应将数据组织为（128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\end{itemize}
输入shape

‘channels\_first’模式下，为形如（samples，channels, rows，cols）的4D张量

‘channels\_last’模式下，为形如（samples，rows, cols，channels）的4D张量

输出shape

‘channels\_first’模式下，为形如（samples，channels, pooled\_rows, pooled\_cols）的4D张量

‘channels\_last’模式下，为形如（samples，pooled\_rows, pooled\_cols，channels）的4D张量

\subsection{AveragePooling3D层}
\begin{python}
keras.layers.pooling.AveragePooling3D(pool_size=(2, 2, 2), strides=None, padding='valid', data_format=None)
\end{python}
为3D信号（空域或时空域）施加平均值池化

本层目前只能在使用Theano为后端时可用

参数
\begin{itemize}
\item pool\_size：整数或长为3的整数tuple，代表在三个维度上的下采样因子，如取（2，2，2）将使信号在每个维度都变为原来的一半长。
\item strides：整数或长为3的整数tuple，或者None，步长值。
\item padding：‘valid’或者‘same’
\item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表数据的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128x128的数据为例，“channels\_first”应将数据组织为（3,128,128,128），而“channels\_last”应将数据组织为（128,128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\item ‘channels\_first’模式下，为形如（samples, channels, len\_pool\_dim1, len\_pool\_dim2, len\_pool\_dim3）的5D张量
\item ‘channels\_last’模式下，为形如（samples, len\_pool\_dim1, len\_pool\_dim2, len\_pool\_dim3，channels, ）的5D张量
\end{itemize}
输出shape

‘channels\_first’模式下，为形如（samples, channels, pooled\_dim1, pooled\_dim2, pooled\_dim3）的5D张量

‘channels\_last’模式下，为形如（samples, pooled\_dim1, pooled\_dim2, pooled\_dim3,channels,）的5D张量

GlobalMaxPooling1D层

keras.layers.pooling.GlobalMaxPooling1D()
对于时间信号的全局最大池化

输入shape

形如（samples，steps，features）的3D张量
输出shape

形如(samples, features)的2D张量
\subsection{GlobalAveragePooling1D层}
\begin{python}
keras.layers.pooling.GlobalAveragePooling1D()
\end{python}
为时域信号施加全局平均值池化

输入shape

形如（samples，steps，features）的3D张量
输出shape

形如(samples, features)的2D张量
\subsection{GlobalMaxPooling2D层}
\begin{python}
keras.layers.pooling.GlobalMaxPooling2D(dim\_ordering='default')
\end{python}
为空域信号施加全局最大值池化

参数
\begin{itemize}
\item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表图像的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128的RGB图像为例，“channels\_first”应将数据组织为（3,128,128），而“channels\_last”应将数据组织为（128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\end{itemize}
输入shape

‘channels\_first’模式下，为形如（samples，channels, rows，cols）的4D张量

‘channels\_last’模式下，为形如（samples，rows, cols，channels）的4D张量

输出shape

形如(nb\_samples, channels)的2D张量

\subsection{GlobalAveragePooling2D层}
\begin{python}
keras.layers.pooling.GlobalAveragePooling2D(dim_ordering='default')
\end{python}
为空域信号施加全局平均值池化

参数
\begin{itemize}
\item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表图像的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128的RGB图像为例，“channels\_first”应将数据组织为（3,128,128），而“channels\_last”应将数据组织为（128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\end{itemize}
输入shape

‘channels\_first’模式下，为形如（samples，channels, rows，cols）的4D张量

‘channels\_last’模式下，为形如（samples，rows, cols，channels）的4D张量

输出shape

形如(nb\_samples, channels)的2D张量
\section{局部连接层LocallyConnceted}

\subsection{LocallyConnected1D层}
\begin{python}
keras.layers.local.LocallyConnected1D(filters, kernel_size, strides=1, padding='valid', data_format=None, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)
\end{python}
LocallyConnected1D层与Conv1D工作方式类似，唯一的区别是不进行权值共享。即施加在不同输入位置的滤波器是不一样的。

参数
\begin{itemize}
\item filters：卷积核的数目（即输出的维度）
\item kernel\_size：整数或由单个整数构成的list/tuple，卷积核的空域或时域窗长度
\item strides：整数或由单个整数构成的list/tuple，为卷积的步长。任何不为1的strides均与任何不为1的dilation\_rata均不兼容
\item padding：补0策略，目前仅支持valid（大小写敏感），same可能会在将来支持。
\item activation：激活函数，为预定义的激活函数名（参考\nameref{ch:activation}），或逐元素（element-wise）的Theano函数。如果不指定该参数，将不会使用任何激活函数（即使用线性激活函数：a(x)=x）
\item dilation\_rate：整数或由单个整数构成的list/tuple，指定dilated convolution中的膨胀比例。任何不为1的dilation\_rata均与任何不为1的strides均不兼容。
\item use\_bias:布尔值，是否使用偏置项
\item kernel\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item bias\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item kernel\_regularizer：施加在权重上的正则项，为Regularizer对象
\item bias\_regularizer：施加在偏置向量上的正则项，为Regularizer对象
\item activity\_regularizer：施加在输出上的正则项，为Regularizer对象
\item kernel\_constraints：施加在权重上的约束项，为Constraints对象
\item bias\_constraints：施加在偏置上的约束项，为Constraints对象
\end{itemize}
输入shape

形如（samples，steps，input\_dim）的3D张量

输出shape

形如（samples，new\_steps，nb\_filter）的3D张量，因为有向量填充的原因，steps的值会改变

\subsection{LocallyConnected2D层}
\begin{python}
keras.layers.local.LocallyConnected2D(filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)
\end{python}
LocallyConnected2D层与Convolution2D工作方式类似，唯一的区别是不进行权值共享。即施加在不同输入patch的滤波器是不一样的，当使用该层作为模型首层时，需要提供参数input\_dim或input\_shape参数。参数含义参考Convolution2D。

参数
\begin{itemize}
\item filters：卷积核的数目（即输出的维度）
\item kernel\_size：单个整数或由两个整数构成的list/tuple，卷积核的宽度和长度。如为单个整数，则表示在各个空间维度的相同长度。
\item strides：单个整数或由两个整数构成的list/tuple，为卷积的步长。如为单个整数，则表示在各个空间维度的相同步长。
\item padding：补0策略，目前仅支持valid（大小写敏感），same可能会在将来支持。
\item activation：激活函数，为预定义的激活函数名（参考\nameref{ch:activation}），或逐元素（element-wise）的Theano函数。如果不指定该参数，将不会使用任何激活函数（即使用线性激活函数：a(x)=x）
\item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表图像的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128的RGB图像为例，“channels\_first”应将数据组织为（3,128,128），而“channels\_last”应将数据组织为（128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\item use\_bias:布尔值，是否使用偏置项
\item kernel\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item bias\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item kernel\_regularizer：施加在权重上的正则项，为Regularizer对象
\item bias\_regularizer：施加在偏置向量上的正则项，为Regularizer对象
\item activity\_regularizer：施加在输出上的正则项，为Regularizer对象
\item kernel\_constraints：施加在权重上的约束项，为Constraints对象
\item bias\_constraints：施加在偏置上的约束项，为Constraints对象
\end{itemize}
输入shape

‘channels\_first’模式下，输入形如（samples,channels，rows，cols）的4D张量

‘channels\_last’模式下，输入形如（samples，rows，cols，channels）的4D张量

注意这里的输入shape指的是函数内部实现的输入shape，而非函数接口应指定的input\_shape，请参考下面提供的例子。

输出shape

‘channels\_first’模式下，为形如（samples，nb\_filter, new\_rows, new\_cols）的4D张量

‘channels\_last’模式下，为形如（samples，new\_rows, new\_cols，nb\_filter）的4D张量

输出的行列数可能会因为填充方法而改变

例子
\begin{python}
# apply a 3x3 unshared weights convolution with 64 output filters on a 32x32 image
# with `data_format="channels_last"`:
model = Sequential()
model.add(LocallyConnected2D(64, (3, 3), input_shape=(32, 32, 3)))
# now model.output_shape == (None, 30, 30, 64)
# notice that this layer will consume (30*30)*(3*3*3*64) + (30*30)*64 parameters

# add a 3x3 unshared weights convolution on top, with 32 output filters:
model.add(LocallyConnected2D(32, (3, 3)))
# now model.output_shape == (None, 28, 28, 32)
\end{python}
\section{循环层Recurrent}

Recurrent层
\begin{python}
keras.layers.recurrent.Recurrent(return_sequences=False, go_backwards=False, stateful=False, unroll=False, implementation=0)
\end{python}
这是循环层的抽象类，请不要在模型中直接应用该层（因为它是抽象类，无法实例化任何对象）。请使用它的子类LSTM，GRU或SimpleRNN。

所有的循环层（LSTM,GRU,SimpleRNN）都服从本层的性质，并接受本层指定的所有关键字参数。

参数
\begin{itemize}
\item weights：numpy array的list，用以初始化权重。该list形如[(input\_dim, output\_dim),(output\_dim, output\_dim),(output\_dim,)]
\item return\_sequences：布尔值，默认False，控制返回类型。若为True则返回整个序列，否则仅返回输出序列的最后一个输出
\item go\_backwards：布尔值，默认为False，若为True，则逆向处理输入序列并返回逆序后的序列
\item stateful：布尔值，默认为False，若为True，则一个batch中下标为i的样本的最终状态将会用作下一个batch同样下标的样本的初始状态。
\item unroll：布尔值，默认为False，若为True，则循环层将被展开，否则就使用符号化的循环。当使用TensorFlow为后端时，循环网络本来就是展开的，因此该层不做任何事情。层展开会占用更多的内存，但会加速RNN的运算。层展开只适用于短序列。
\item implementation：0，1或2， 若为0，则RNN将以更少但是更大的矩阵乘法实现，因此在CPU上运行更快，但消耗更多的内存。如果设为1，则RNN将以更多但更小的矩阵乘法实现，因此在CPU上运行更慢，在GPU上运行更快，并且消耗更少的内存。如果设为2（仅LSTM和GRU可以设为2），则RNN将把输入门、遗忘门和输出门合并为单个矩阵，以获得更加在GPU上更加高效的实现。注意，RNN dropout必须在所有门上共享，并导致正则效果性能微弱降低。
\item input\_dim：输入维度，当使用该层为模型首层时，应指定该值（或等价的指定input\_shape)
\item input\_length：当输入序列的长度固定时，该参数为输入序列的长度。当需要在该层后连接Flatten层，然后又要连接Dense层时，需要指定该参数，否则全连接的输出无法计算出来。注意，如果循环层不是网络的第一层，你需要在网络的第一层中指定序列的长度（通过input\_shape指定）。
\end{itemize}
输入shape

形如（samples，timesteps，input\_dim）的3D张量

输出shape

如果return\_sequences=True：返回形如（samples，timesteps，output\_dim）的3D张量

否则，返回形如（samples，output\_dim）的2D张量

例子
\begin{python}
# as the first layer in a Sequential model
model = Sequential()
model.add(LSTM(32, input_shape=(10, 64)))
# now model.output_shape == (None, 32)
# note: `None` is the batch dimension.

# the following is identical:
model = Sequential()
model.add(LSTM(32, input_dim=64, input_length=10))

# for subsequent layers, no need to specify the input size:
         model.add(LSTM(16))

# to stack recurrent layers, you must use return_sequences=True
# on any recurrent layer that feeds into another recurrent layer.
# note that you only need to specify the input size on the first layer.
model = Sequential()
model.add(LSTM(64, input_dim=64, input_length=10, return_sequences=True))
model.add(LSTM(32, return_sequences=True))
model.add(LSTM(10))
\end{python}
指定RNN初始状态的注意事项

可以通过设置initial\_state用符号式的方式指定RNN层的初始状态。即，initial\_stat的值应该为一个tensor或一个tensor列表，代表RNN层的初始状态。

也可以通过设置reset\_states参数用数值的方法设置RNN的初始状态，状态的值应该为numpy数组或numpy数组的列表，代表RNN层的初始状态。

屏蔽输入数据（Masking）

循环层支持通过时间步变量对输入数据进行Masking，如果想将输入数据的一部分屏蔽掉，请使用Embedding层并将参数mask\_zero设为True。

使用状态RNN的注意事项

可以将RNN设置为‘stateful’，意味着由每个batch计算出的状态都会被重用于初始化下一个batch的初始状态。状态RNN假设连续的两个batch之中，相同下标的元素有一一映射关系。

要启用状态RNN，请在实例化层对象时指定参数stateful=True，并在Sequential模型使用固定大小的batch：通过在模型的第一层传入batch\_size=(...)和input\_shape来实现。在函数式模型中，对所有的输入都要指定相同的batch\_size。

如果要将循环层的状态重置，请调用.reset\_states()，对模型调用将重置模型中所有状态RNN的状态。对单个层调用则只重置该层的状态。

\subsection{SimpleRNN层}
\begin{python}
keras.layers.recurrent.SimpleRNN(units, activation='tanh', use_bias=True, kernel_initializer='glorot_uniform', recurrent_initializer='orthogonal', bias_initializer='zeros', kernel_regularizer=None, recurrent_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, recurrent_constraint=None, bias_constraint=None, dropout=0.0, recurrent_dropout=0.0)
\end{python}
全连接RNN网络，RNN的输出会被回馈到输入

参数
\begin{itemize}
\item units：输出维度
\item activation：激活函数，为预定义的激活函数名,参考\nameref{ch:activation}
\item use\_bias: 布尔值，是否使用偏置项
\item kernel\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item recurrent\_initializer：循环核的初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item bias\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item kernel\_regularizer：施加在权重上的正则项，为Regularizer对象
\item bias\_regularizer：施加在偏置向量上的正则项，为Regularizer对象
\item recurrent\_regularizer：施加在循环核上的正则项，为Regularizer对象
\item activity\_regularizer：施加在输出上的正则项，为Regularizer对象
\item kernel\_constraints：施加在权重上的约束项，为Constraints对象
\item recurrent\_constraints：施加在循环核上的约束项，为Constraints对象
\item bias\_constraints：施加在偏置上的约束项，为Constraints对象
\item dropout：0~1之间的浮点数，控制输入线性变换的神经元断开比例
\item recurrent\_dropout：0~1之间的浮点数，控制循环状态的线性变换的神经元断开比例
\end{itemize}
参考文献
\begin{itemize}
\item \href{https://arxiv.org/pdf/1512.05287.pdf}{A Theoretically Grounded Application of Dropout in Recurrent Neural Networks}
\end{itemize}
\subsection{GRU层}
\begin{python}
keras.layers.recurrent.GRU(units, activation='tanh', recurrent_activation='hard_sigmoid', use_bias=True, kernel_initializer='glorot_uniform', recurrent_initializer='orthogonal', bias_initializer='zeros', kernel_regularizer=None, recurrent_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, recurrent_constraint=None, bias_constraint=None, dropout=0.0, recurrent_dropout=0.0)
\end{python}
门限循环单元（详见参考文献）

参数
\begin{itemize}
\item units：输出维度
\item activation：激活函数，为预定义的激活函数名（参考\nameref{ch:activation}）
\item use\_bias: 布尔值，是否使用偏置项
\item kernel\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item recurrent\_initializer：循环核的初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item bias\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item kernel\_regularizer：施加在权重上的正则项，为Regularizer对象
\item bias\_regularizer：施加在偏置向量上的正则项，为Regularizer对象
\item recurrent\_regularizer：施加在循环核上的正则项，为Regularizer对象
\item activity\_regularizer：施加在输出上的正则项，为Regularizer对象
\item kernel\_constraints：施加在权重上的约束项，为Constraints对象
\item recurrent\_constraints：施加在循环核上的约束项，为Constraints对象
\item bias\_constraints：施加在偏置上的约束项，为Constraints对象
\item dropout：0~1之间的浮点数，控制输入线性变换的神经元断开比例
\item recurrent\_dropout：0~1之间的浮点数，控制循环状态的线性变换的神经元断开比例
\end{itemize}
参考文献
\begin{itemize}
\item \href{http://www.aclweb.org/anthology/W14-4012}{On the Properties of Neural Machine Translation: Encoder–Decoder Approaches}
\item \href{https://arxiv.org/pdf/1412.3555v1.pdf}{Empirical Evaluation of Gated Recurrent Neural Networks on Sequence Modeling}
\item \href{https://arxiv.org/pdf/1512.05287.pdf}{A Theoretically Grounded Application of Dropout in Recurrent Neural Networks}
\end{itemize}
\subsection{LSTM层}
\begin{python}
keras.layers.recurrent.LSTM(units, activation='tanh', recurrent_activation='hard_sigmoid', use_bias=True, kernel_initializer='glorot_uniform', recurrent_initializer='orthogonal', bias_initializer='zeros', unit_forget_bias=True, kernel_regularizer=None, recurrent_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, recurrent_constraint=None, bias_constraint=None, dropout=0.0, recurrent_dropout=0.0)
\end{python}
Keras长短期记忆模型，关于此算法的详情，请参考本教程
参数
\begin{itemize}
\item units：输出维度
\item activation：激活函数，为预定义的激活函数名（参考\nameref{ch:activation}）
\item recurrent\_activation: 为循环步施加的激活函数（参考\nameref{ch:activation}）
\item use\_bias: 布尔值，是否使用偏置项
\item kernel\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item recurrent\_initializer：循环核的初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item bias\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item kernel\_regularizer：施加在权重上的正则项，为Regularizer对象
\item bias\_regularizer：施加在偏置向量上的正则项，为Regularizer对象
\item recurrent\_regularizer：施加在循环核上的正则项，为Regularizer对象
\item activity\_regularizer：施加在输出上的正则项，为Regularizer对象
\item kernel\_constraints：施加在权重上的约束项，为Constraints对象
\item recurrent\_constraints：施加在循环核上的约束项，为Constraints对象
\item bias\_constraints：施加在偏置上的约束项，为Constraints对象
\item dropout：0~1之间的浮点数，控制输入线性变换的神经元断开比例
\item recurrent\_dropout：0~1之间的浮点数，控制循环状态的线性变换的神经元断开比例
\end{itemize}
参考文献
\begin{itemize}
\item \href{https://arxiv.org/pdf/1512.05287.pdf}{Long short-term memory（original 1997 paper）}
\item \href{http://www.mitpressjournals.org/doi/abs/10.1162/089976600300015015?journalCode=neco}{Learning to forget: Continual prediction with LSTM}
\item \href{http://www.cs.toronto.edu/~graves/preprint.pdf}{Supervised sequence labelling with recurrent neural networks}
\item \href{https://arxiv.org/pdf/1512.05287.pdf}{A Theoretically Grounded Application of Dropout in Recurrent Neural Networks}
\end{itemize}
\section{嵌入层 Embedding}

Embedding层
\begin{python}
keras.layers.embeddings.Embedding(
input_dim, output_dim,
embeddings_initializer='uniform',
embeddings_regularizer=None,
activity_regularizer=None,
embeddings_constraint=None,
mask_zero=False,
input_length=None)
\end{python}
嵌入层将正整数（下标）转换为具有固定大小的向量，如[[4],[20]]->[[0.25,0.1],[0.6,-0.2]]

Embedding层只能作为模型的第一层

参数
\begin{itemize}
\item input\_dim：大或等于0的整数，字典长度，即输入数据最大下标+1
\item output\_dim：大于0的整数，代表全连接嵌入的维度
\item embeddings\_initializer: 嵌入矩阵的初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item embeddings\_regularizer: 嵌入矩阵的正则项，为Regularizer对象
\item embeddings\_constraint: 嵌入矩阵的约束项，为Constraints对象
\item mask\_zero：布尔值，确定是否将输入中的‘0’看作是应该被忽略的‘填充’（padding）值，该参数在使用递归层处理变长输入时有用。设置为True的话，模型中后续的层必须都支持masking，否则会抛出异常。如果该值为True，则下标0在字典中不可用，input\_dim应设置为|vocabulary| + 2。
\item input\_length：当输入序列的长度固定时，该值为其长度。如果要在该层后接Flatten层，然后接Dense层，则必须指定该参数，否则Dense层的输出维度无法自动推断。
\end{itemize}
输入shape

形如（samples，sequence\_length）的2D张量

输出shape

形如(samples, sequence\_length, output\_dim)的3D张量

例子
\begin{python}
model = Sequential()
model.add(Embedding(1000, 64, input_length=10))
# the model will take as input an integer matrix of size (batch, input_length).
# the largest integer (i.e. word index) in the input should be no larger than 999 (vocabulary size).
# now model.output_shape == (None, 10, 64), where None is the batch dimension.

input_array = np.random.randint(1000, size=(32, 10))

model.compile('rmsprop', 'mse')
output_array = model.predict(input_array)
assert output_array.shape == (32, 10, 64)
\end{python}
参考文献
\begin{itemize}
\item \href{https://arxiv.org/pdf/1512.05287}{A Theoretically Grounded Application of Dropout in Recurrent Neural Networks}
\end{itemize}
\section{Merge层}

Merge层提供了一系列用于融合两个层或两个张量的层对象和方法。以大写首字母开头的是Layer类，以小写字母开头的是张量的函数。小写字母开头的张量函数在内部实际上是调用了大写字母开头的层。

\subsection{Add}

keras.layers.merge.Add()
将Layer that adds a list of inputs.

该层接收一个列表的同shape张量，并返回它们的和，shape不变。

\subsection{Multiply}
\begin{itemize}
\item keras.layers.merge.Multiply()
\end{itemize}

该层接收一个列表的同shape张量，并返回它们的逐元素积的张量，shape不变。

\subsection{Average}
\begin{itemize}
    \item keras.layers.merge.Average()
\end{itemize}
该层接收一个列表的同shape张量，并返回它们的逐元素均值，shape不变。

\subsection{Maximum}
\begin{itemize}
    \item keras.layers.merge.Maximum()
\end{itemize}
该层接收一个列表的同shape张量，并返回它们的逐元素最大值，shape不变。

\subsection{Concatenate}
\begin{python}
keras.layers.merge.Concatenate(axis=-1)
\end{python}
该层接收一个列表的同shape张量，并返回它们的按照给定轴相接构成的向量。

参数
\begin{itemize}
    \item axis: 想接的轴
    \item **kwargs: 普通的Layer关键字参数
\end{itemize}
\begin{python}
keras.layers.merge.Dot(axes, normalize=False)
\end{python}
计算两个tensor中样本的张量乘积。例如，如果两个张量a和b的shape都为（batch\_size, n），则输出为形如（batch\_size,1）的张量，结果张量每个batch的数据都是a[i,:]和b[i,:]的矩阵（向量）点积。

参数
\begin{itemize}
    \item axes: 整数或整数的tuple，执行乘法的轴。
    \item normalize: 布尔值，是否沿执行成绩的轴做L2规范化，如果设为True，那么乘积的输出是两个样本的余弦相似性。
    \item **kwargs: 普通的Layer关键字参数
\end{itemize}
\subsection{add}

add(inputs)
Add层的函数式包装

参数：
\begin{itemize}
    \item inputs: 长度至少为2的张量列表A
    \item **kwargs: 普通的Layer关键字参数
\end{itemize}
返回值

输入列表张量之和

\subsection{multiply}

Multiply的函数包装
\begin{itemize}
    \item inputs: 长度至少为2的张量列表
    \item  **kwargs: 普通的Layer关键字参数
\end{itemize}
返回值

输入列表张量之逐元素积

\subsection{average}
average(inputs)
Average的函数包装

参数：
\begin{itemize}
\item inputs: 长度至少为2的张量列表
\item **kwargs: 普通的Layer关键字参数
\end{itemize}
返回值

输入列表张量之逐元素均值

\subsection{maximum}

maximum(inputs)
Maximum的函数包装

参数：
\begin{itemize}
\item inputs: 长度至少为2的张量列表
\item **kwargs: 普通的Layer关键字参数
\end{itemize}
返回值

输入列表张量之逐元素均值

\subsection{concatenate}

concatenate(inputs, axis=-1))
Concatenate的函数包装

参数
\begin{itemize}
\item inputs: 长度至少为2的张量列
\item axis: 相接的轴
\item **kwargs: 普通的Layer关键字参数
\end{itemize}
\subsection{dot}

dot(inputs, axes, normalize=False)
Dot的函数包装

参数
\begin{itemize}
\item inputs: 长度至少为2的张量列
\item axes: 整数或整数的tuple，执行乘法的轴。
\item normalize: 布尔值，是否沿执行成绩的轴做L2规范化，如果设为True，那么乘积的输出是两个样本的余弦相似性。
\item **kwargs: 普通的Layer关键字参数
\end{itemize}
\section{dvanced Activation}

\subsection{LeakyReLU层}
\begin{python}
keras.layers.advanced_activations.LeakyReLU(alpha=0.3)
\end{python}
LeakyRelU是修正线性单元（Rectified Linear Unit，ReLU）的特殊版本，当不激活时，LeakyReLU仍然会有非零输出值，从而获得一个小梯度，避免ReLU可能出现的神经元“死亡”现象。即，f(x)=alpha * x for x < 0, f(x) = x for x>=0
参数
\begin{itemize}
\item alpha：大于0的浮点数，代表激活函数图像中第三象限线段的斜率
\end{itemize}
输入shape

任意，当使用该层为模型首层时需指定input\_shape参数

输出shape

与输入相同

参考文献

\href{https://web.stanford.edu/~awni/papers/relu_hybrid_icml2013_final.pdf}{Rectifier Nonlinearities Improve Neural Network Acoustic Models}

\subsection{PReLU层}
\begin{python}
keras.layers.advanced_activations.PReLU(alpha_initializer='zeros', alpha_regularizer=None, alpha_constraint=None, shared_axes=None)
\end{python}
该层为参数化的ReLU（Parametric ReLU），表达式是：f(x) = alpha * x for x < 0,  f(x) = x for x>=0，此处的alpha为一个与xshape相同的可学习的参数向量。

参数
\begin{itemize}
\item alpha\_initializer：alpha的初始化函数
\item alpha\_regularizer：alpha的正则项
\item alpha\_constraint：alpha的约束项
\item shared\_axes：该参数指定的轴将共享同一组科学系参数，例如假如输入特征图是从2D卷积过来的，具有形如(batch, height, width, channels)这样的shape，则或许你会希望在空域共享参数，这样每个filter就只有一组参数，设定shared\_axes=[1,2]可完成该目标
\end{itemize}
输入shape

任意，当使用该层为模型首层时需指定input\_shape参数

输出shape

与输入相同

参考文献

\href{http://arxiv.org/pdf/1502.01852v1.pdf}{Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification}
\subsection{ELU层}
\begin{python}
keras.layers.advanced_activations.ELU(alpha=1.0)
\end{python}
ELU层是指数线性单元（Exponential Linera Unit），表达式为： 该层为参数化的ReLU（Parametric ReLU），表达式是：f(x) = alpha * (exp(x) - 1.) for x < 0, f(x) = x for x>=0

参数
\begin{itemize}
\item alpha：控制负因子的参数
\end{itemize}
输入shape

任意，当使用该层为模型首层时需指定input\_shape参数

输出shape

与输入相同

参考文献

\href{https://arxiv.org/pdf/1511.07289v1.pdf}{Fast and Accurate Deep Network Learning by Exponential Linear Units (ELUs)}
%\href{ThresholdedReLU层}
\begin{python}
keras.layers.advanced_activations.ThresholdedReLU(theta=1.0)
\end{python}
该层是带有门限的ReLU，表达式是：f(x) = x for x > theta,f(x) = 0 otherwise

参数
\begin{itemize}
\item theata：大或等于0的浮点数，激活门限位置
\end{itemize}
输入shape

任意，当使用该层为模型首层时需指定input\_shape参数

输出shape

与输入相同

参考文献

\href{http://arxiv.org/pdf/1402.3337.pdf}{Zero-Bias Autoencoders and the Benefits of Co-Adapting Features}
\section{（批）规范化BatchNormalization}

BatchNormalization层
\begin{python}
keras.layers.normalization.BatchNormalization(axis=-1, momentum=0.99, epsilon=0.001, center=True, scale=True, beta_initializer='zeros', gamma_initializer='ones', moving_mean_initializer='zeros', moving_variance_initializer='ones', beta_regularizer=None, gamma_regularizer=None, beta_constraint=None, gamma_constraint=None)
\end{python}
该层在每个batch上将前一层的激活值重新规范化，即使得其输出数据的均值接近0，其标准差接近1

参数
\begin{itemize}
\item axis: 整数，指定要规范化的轴，通常为特征轴。例如在进行data\_format="channels\_first的2D卷积后，一般会设axis=1。
\item momentum: 动态均值的动量
\item epsilon：大于0的小浮点数，用于防止除0错误
\item center: 若设为True，将会将beta作为偏置加上去，否则忽略参数beta
\item scale: 若设为True，则会乘以gamma，否则不使用gamma。当下一层是线性的时，可以设False，因为scaling的操作将被下一层执行。
\item beta\_initializer：beta权重的初始方法
\item gamma\_initializer: gamma的初始化方法
\item moving\_mean\_initializer: 动态均值的初始化方法
\item moving\_variance\_initializer: 动态方差的初始化方法
\item beta\_regularizer: 可选的beta正则
\item gamma\_regularizer: 可选的gamma正则
\item beta\_constraint: 可选的beta约束
\item gamma\_constraint: 可选的gamma约束
\end{itemize}
输入shape

任意，当使用本层为模型首层时，指定input\_shape参数时有意义。

输出shape

与输入shape相同

参考文献
\begin{itemize}
    \item \href{http://arxiv.org/pdf/1502.03167v3.pdf}{Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift}
\end{itemize}
\begin{quote}
BN层的作用

（1）加速收敛 （2）控制过拟合，可以少用或不用Dropout和正则 （3）降低网络对初始化权重不敏感 （4）允许使用较大的学习率
\end{quote}
\section{噪声层Noise}

GaussianNoise层
\begin{python}
keras.layers.noise.GaussianNoise(stddev)
\end{python}
为数据施加0均值，标准差为stddev的加性高斯噪声。该层在克服过拟合时比较有用，你可以将它看作是随机的数据提升。高斯噪声是需要对输入数据进行破坏时的自然选择。

因为这是一个起正则化作用的层，该层只在训练时才有效。

参数
\begin{itemize}
    \item stddev：浮点数，代表要产生的高斯噪声标准差
\end{itemize}
输入shape

任意，当使用该层为模型首层时需指定input\_shape参数

输出shape

与输入相同

\subsection{GaussianDropout层}
\begin{python}
keras.layers.noise.GaussianDropout(rate)
\end{python}
为层的输入施加以1为均值，标准差为sqrt(rate/(1-rate)的乘性高斯噪声

因为这是一个起正则化作用的层，该层只在训练时才有效。

参数
\begin{itemize}
    \item rate：浮点数，断连概率，与Dropout层相同
\end{itemize}
输入shape

任意，当使用该层为模型首层时需指定input\_shape参数

输出shape

与输入相同

参考文献

\href{http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf}{Dropout: A Simple Way to Prevent Neural Networks from Overfitting}
\section{包装器Wrapper}

TimeDistributed包装器
\begin{python}
keras.layers.wrappers.TimeDistributed(layer)
\end{python}
该包装器可以把一个层应用到输入的每一个时间步上

参数
\begin{itemize}
\item layer：Keras层对象
\end{itemize}
输入至少为3D张量，下标为1的维度将被认为是时间维

例如，考虑一个含有32个样本的batch，每个样本都是10个向量组成的序列，每个向量长为16，则其输入维度为(32,10,16)，其不包含batch大小的input\_shape为(10,16)

我们可以使用包装器TimeDistributed包装Dense，以产生针对各个时间步信号的独立全连接：
\begin{python}
# as the first layer in a model
model = Sequential()
model.add(TimeDistributed(Dense(8), input_shape=(10, 16)))
# now model.output_shape == (None, 10, 8)

# subsequent layers: no need for input_shape
model.add(TimeDistributed(Dense(32)))
# now model.output_shape == (None, 10, 32)
\end{python}
程序的输出数据shape为(32,10,8)

使用TimeDistributed包装Dense严格等价于layers.TimeDistribuedDense。不同的是包装器TimeDistribued还可以对别的层进行包装，如这里对Convolution2D包装：
\begin{python}
model = Sequential()
model.add(TimeDistributed(Convolution2D(64, 3, 3), input_shape=(10, 3, 299, 299)))
\end{python}
\subsection{Bidirectional包装器}
\begin{python}
keras.layers.wrappers.Bidirectional(layer, merge_mode='concat', weights=None)
\end{python}
\subsection{双向RNN包装器}

参数
\begin{itemize}
\item layer：Recurrent对象
\item merge\_mode：前向和后向RNN输出的结合方式，为sum,mul,concat,ave和None之一，若设为None，则返回值不结合，而是以列表的形式返回
\end{itemize}
例子
\begin{python}
model = Sequential()
model.add(Bidirectional(LSTM(10, return_sequences=True), input_shape=(5, 10)))
model.add(Bidirectional(LSTM(10)))
model.add(Dense(5))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
\end{python}
\section{编写自己的层}

对于简单的定制操作，我们或许可以通过使用layers.core.Lambda层来完成。但对于任何具有可训练权重的定制层，你应该自己来实现。

这里是一个Keras2的层应该具有的框架结构(如果你的版本更旧请升级)，要定制自己的层，你需要实现下面三个方法
\begin{itemize}
\item build(input\_shape)：这是定义权重的方法，可训练的权应该在这里被加入列表`self.trainable\_weights中。其它的属性还包括self.non\_trainabe\_weights（列表）和self.updates（需要更新的形如（tensor, new\_tensor）的tuple的列表）。你可以参考BatchNormalization层的实现来学习如何使用上面两个属性。这个方法必须设置self.built = True，可通过调用super([layer],self).build()实现
\item call(x)：这是定义层功能的方法，除非你希望你写的层支持masking，否则你只需要关心call的第一个参数：输入张量
\item compute\_output\_shape(input\_shape)：如果你的层修改了输入数据的shape，你应该在这里指定shape变化的方法，这个函数使得Keras可以做自动shape推断
\end{itemize}
\begin{python}
from keras import backend as K
from keras.engine.topology import Layer
import numpy as np

class MyLayer(Layer):

    def __init__(self, output_dim, **kwargs):
        self.output_dim = output_dim
        super(MyLayer, self).__init__(**kwargs)

    def build(self, input_shape):
        # Create a trainable weight variable for this layer.
        self.kernel = self.add_weight(shape=(input_shape[1], self.output_dim),
                                      initializer='uniform',
                                      trainable=True)
        super(MyLayer, self).build(input_shape)  # Be sure to call this somewhere!

    def call(self, x):
        return K.dot(x, self.kernel)

    def compute_output_shape(self, input_shape):
        return (input_shape[0], self.output_dim)
\end{python}
现存的Keras层代码可以为你的实现提供良好参考，阅读源代码吧！
\chapter{网络层}\label{ch:network}
关于Keras的“层”（Layer）

所有的Keras层对象都有如下方法：
\begin{itemize}
    \item layer.get\_weights()：返回层的权重（numpy array）
    \item layer.set\_weights(weights)：从numpy array中将权重加载到该层中，要求numpy array的形状与* layer.get\_weights()的形状相同
    \item layer.get\_config()：返回当前层配置信息的字典，层也可以借由配置信息重构:
\end{itemize}
\begin{python}
layer = Dense(32)
config = layer.get_config()
reconstructed_layer = Dense.from_config(config)
\end{python}
或者：
\begin{python}
from keras import layers

config = layer.get_config()
layer = layers.deserialize({'class_name': layer.__class__.__name__,
                            'config': config})
\end{python}
如果层仅有一个计算节点（即该层不是共享层），则可以通过下列方法获得输入张量、输出张量、输入数据的形状和输出数据的形状：
\begin{itemize}
\item layer.input
\item layer.output
\item layer.input\_shape
\item layer.output\_shape
\end{itemize}
如果该层有多个计算节点（参考\href{http://keras-cn.readthedocs.io/en/latest/getting_started/functional_API/#node}{层计算节点和共享层}）。可以使用下面的方法
\begin{itemize}
\item layer.get\_input\_at(node\_index)
\item layer.get\_output\_at(node\_index)
\item layer.get\_input\_shape\_at(node\_index)
\item layer.get\_output\_shape\_at(node\_index)
\end{itemize}
\section{常用层}\label{sec:common}

常用层对应于core模块，core内部定义了一系列常用的网络层，包括全连接、激活层等

\subsection{Dense层}
\begin{python}
keras.layers.core.Dense(units, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)
\end{python}
Dense就是常用的全连接层，所实现的运算是output = activation(dot(input, kernel)+bias)。其中activation是逐元素计算的激活函数，kernel是本层的权值矩阵，bias为偏置向量，只有当use\_bias=True才会添加。

如果本层的输入数据的维度大于2，则会先被压为与kernel相匹配的大小。

这里是一个使用示例：
\begin{python}
# as first layer in a sequential model:
model = Sequential()
model.add(Dense(32, input_shape=(16,)))
# now the model will take as input arrays of shape (*, 16)
# and output arrays of shape (*, 32)

# after the first layer, you don't need to specify
# the size of the input anymore:
model.add(Dense(32))
\end{python}
参数：
\begin{itemize}
    \item units：大于0的整数，代表该层的输出维度。
    \item activation：激活函数，为预定义的激活函数名（参考\nameref{ch:activation}），或逐元素（element-wise）的Theano函数。如果不指定该参数，将不会使用任何激活函数（即使用线性激活函数：a(x)=x）
    \item use\_bias: 布尔值，是否使用偏置项
    \item kernel\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
    \item bias\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
    \item kernel\_regularizer：施加在权重上的正则项，为Regularizer对象
    \item bias\_regularizer：施加在偏置向量上的正则项，为Regularizer对象
    \item activity\_regularizer：施加在输出上的正则项，为Regularizer对象
    \item kernel\_constraints：施加在权重上的约束项，为Constraints对象
    \item bias\_constraints：施加在偏置上的约束项，为Constraints对象
\end{itemize}
输入

形如(nb\_samples,\ldots, input\_shape[1])的nD张量，最常见的情况为(nb\_samples, input\_dim)的2D张量

输出

形如(nb\_samples, \ldots, units)的nD张量，最常见的情况为(nb\_samples, output\_dim)的2D张量


\subsection{Activation层}


keras.layers.core.Activation(activation)
激活层对一个层的输出施加激活函数

参数
\begin{itemize}
\item activation：将要使用的激活函数，为预定义激活函数名或一个Tensorflow/Theano的函数。参考\nameref{ch:activation}
\end{itemize}
输入shape任意，当使用激活层作为第一层时，要指定input\_shape\newline
输出shape与输入shape相同

\subsection{Dropout层}
\begin{python}
keras.layers.core.Dropout(rate, noise_shape=None, seed=None)
\end{python}
为输入数据施加Dropout。Dropout将在训练过程中每次更新参数时随机断开一定百分比（rate）的输入神经元，Dropout层用于防止过拟合。

参数
\begin{itemize}
    \item rate：0~1的浮点数，控制需要断开的神经元的比例
    \item noise\_shape：整数张量，为将要应用在输入上的二值Dropout mask的shape，例如你的输入为(batch\_size, timesteps, features)，并且你希望在各个时间步上的Dropout mask都相同，则可传入noise\_shape=(batch\_size, 1, features)。
    \item seed：整数，使用的随机数种子
\end{itemize}
参考文献

\href{http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf}{Dropout: A Simple Way to Prevent Neural Networks from Overfitting}
\subsection{Flatten层}

keras.layers.core.Flatten()
Flatten层用来将输入“压平”，即把多维的输入一维化，常用在从卷积层到全连接层的过渡。Flatten不影响batch的大小。

例子
\begin{python}
model = Sequential()
model.add(Convolution2D(64, 3, 3,
            border_mode='same',
            input_shape=(3, 32, 32)))
# now: model.output_shape == (None, 64, 32, 32)

model.add(Flatten())
# now: model.output_shape == (None, 65536)
\end{python}
\subsection{Reshape层}
\begin{python}
keras.layers.core.Reshape(target_shape)
\end{python}
Reshape层用来将输入shape转换为特定的shape

参数
\begin{itemize}
    \item target\_shape：目标shape，为整数的tuple，不包含样本数目的维度（batch大小）
\end{itemize}
输入shape任意，但输入的shape必须固定。当使用该层为模型首层时，需要指定input\_shape参数。

输出shape

(batch\_size,)+target\_shape

例子
\begin{python}
# as first layer in a Sequential model
model = Sequential()
model.add(Reshape((3, 4), input_shape=(12,)))
# now: model.output_shape == (None, 3, 4)
# note: `None` is the batch dimension

# as intermediate layer in a Sequential model
model.add(Reshape((6, 2)))
# now: model.output_shape == (None, 6, 2)

# also supports shape inference using `-1` as dimension
model.add(Reshape((-1, 2, 2)))
# now: model.output_shape == (None, 3, 2, 2)
\end{python}
\subsection{Permute层}
\begin{python}
keras.layers.core.Permute(dims)
\end{python}
Permute层将输入的维度按照给定模式进行重排，例如，当需要将RNN和CNN网络连接时，可能会用到该层。

参数
\begin{itemize}
    \item dims：整数tuple，指定重排的模式，不包含样本数的维度。重排模式的下标从1开始。例如（2，1）代表将输入的第二个维度重排到输出的第一个维度，而将输入的第一个维度重排到第二个维度
例子
\end{itemize}
\begin{python}
model = Sequential()
model.add(Permute((2, 1), input_shape=(10, 64)))
# now: model.output_shape == (None, 64, 10)
# note: `None` is the batch dimension
\end{python}
输入shape任意，当使用激活层作为第一层时，要指定input\_shape\newline
输出shape与输入相同，但是其维度按照指定的模式重新排列

\subsection{RepeatVector层}
\begin{python}
keras.layers.core.RepeatVector(n)
\end{python}
参数
\begin{itemize}
    \item n：整数，重复的次数
\end{itemize}
输入shape形如（nb\_samples, features）的2D张量\newline
输出shape形如（nb\_samples, n, features）的3D张量

例子
\begin{python}
model = Sequential()
model.add(Dense(32, input_dim=32))
# now: model.output_shape == (None, 32)
# note: `None` is the batch dimension

model.add(RepeatVector(3))
# now: model.output_shape == (None, 3, 32)
\end{python}
\subsection{Lambda层}
\begin{python}
keras.layers.core.Lambda(function, output_shape=None, mask=None, arguments=None)
\end{python}
本函数用以对上一层的输出施以任何Theano/TensorFlow表达式

参数
\begin{itemize}
    \item function：要实现的函数，该函数仅接受一个变量，即上一层的输出
    \item output\_shape：函数应该返回的值的shape，可以是一个tuple，也可以是一个根据输入shape计算输出shape的函数
    \item mask: 掩膜
    \item arguments：可选，字典，用来记录向函数中传递的其它关键字参数
\end{itemize}
例子
\begin{python}
# add a x -> x\^2 layer
model.add(Lambda(lambda x: x ** 2))
# add a layer that returns the concatenation
# of the positive part of the input and
# the opposite of the negative part

def antirectifier(x):
    x -= K.mean(x, axis=1, keepdims=True)
    x = K.l2_normalize(x, axis=1)
    pos = K.relu(x)
    neg = K.relu(-x)
    return K.concatenate([pos, neg], axis=1)

def antirectifier_output_shape(input_shape):
    shape = list(input_shape)
    assert len(shape) == 2  # only valid for 2D tensors
    shape[-1] *= 2
    return tuple(shape)

model.add(Lambda(antirectifier,
         output_shape=antirectifier_output_shape))
\end{python}
输入shape任意，当使用该层作为第一层时，要指定input\_shape\newline
输出shape由output\_shape参数指定的输出shape，当使用tensorflow时可自动推断

\subsection{ActivityRegularizer层}
\begin{python}
keras.layers.core.ActivityRegularization(l1=0.0, l2=0.0)
\end{python}
经过本层的数据不会有任何变化，但会基于其激活值更新损失函数值

参数
\begin{itemize}
    \item l1：1范数正则因子（正浮点数）
    \item l2：2范数正则因子（正浮点数）
\end{itemize}
输入shape任意，当使用该层作为第一层时，要指定input\_shape\newline
输出shape与输入shape相同

\subsection{Masking层}
\begin{python}
keras.layers.core.Masking(mask_value=0.0)
\end{python}
使用给定的值对输入的序列信号进行“屏蔽”，用以定位需要跳过的时间步

对于输入张量的时间步，即输入张量的第1维度（维度从0开始算，见例子），如果输入张量在该时间步上都等于mask\_value，则该时间步将在模型接下来的所有层（只要支持masking）被跳过（屏蔽）。

如果模型接下来的一些层不支持masking，却接受到masking过的数据，则抛出异常。

例子

考虑输入数据x是一个形如(samples,timesteps,features)的张量，现将其送入LSTM层。因为你缺少时间步为3和5的信号，所以你希望将其掩盖。这时候应该：

赋值x[:,3,:] = 0.，x[:,5,:] = 0.
在LSTM层之前插入mask\_value=0.的Masking层
\begin{itemize}
    \item model = Sequential()
    \item model.add(Masking(mask\_value=0., input\_shape=(timesteps, features)))
model.add(LSTM(32))
\end{itemize}
\section{卷积层}

\subsection{Conv1D层}
\begin{python}
keras.layers.convolutional.Conv1D(filters, kernel_size, strides=1, padding='valid', dilation_rate=1, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)
\end{python}
一维卷积层（即时域卷积），用以在一维输入信号上进行邻域滤波。当使用该层作为首层时，需要提供关键字参数input\_shape。例如(10,128)代表一个长为10的序列，序列中每个信号为128向量。而(None, 128)代表变长的128维向量序列。

该层生成将输入信号与卷积核按照单一的空域（或时域）方向进行卷积。如果use\_bias=True，则还会加上一个偏置项，若activation不为None，则输出为经过激活函数的输出。

参数
\begin{itemize}
\item filters：卷积核的数目（即输出的维度）
\item kernel\_size：整数或由单个整数构成的list/tuple，卷积核的空域或时域窗长度
strides：整数或由单个整数构成的list/tuple，为卷积的步长。任何不为1的strides均与任何不为1的dilation\_rata均不兼容
\item padding：补0策略，为“valid”, “same” 或“causal”，“causal”将产生因果（膨胀的）卷积，即output[t]不依赖于input[t+1：]。当对不能违反时间顺序的时序信号建模时有用。参考WaveNet: A Generative Model for Raw Audio, section 2.1.。“valid”代表只进行有效的卷积，即对边界数据不处理。“same”代表保留边界处的卷积结果，通常会导致输出shape与输入shape相同。
\item activation：激活函数，为预定义的激活函数名（参考\nameref{ch:activation}），或逐元素（element-wise）的Theano函数。如果不指定该参数，将不会使用任何激活函数（即使用线性激活函数：a(x)=x）
\item dilation\_rate：整数或由单个整数构成的list/tuple，指定dilated convolution中的膨胀比例。任何不为1的dilation\_rata均与任何不为1的strides均不兼容。
\item use\_bias:布尔值，是否使用偏置项
\item kernel\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item bias\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item kernel\_regularizer：施加在权重上的正则项，为Regularizer对象
\item bias\_regularizer：施加在偏置向量上的正则项，为Regularizer对象
\item activity\_regularizer：施加在输出上的正则项，为Regularizer对象
\item kernel\_constraints：施加在权重上的约束项，为Constraints对象
\item bias\_constraints：施加在偏置上的约束项，为Constraints对象
\end{itemize}
输入shape

形如（samples，steps，input\_dim）的3D张量

输出shape

形如（samples，new\_steps，nb\_filter）的3D张量，因为有向量填充的原因，steps的值会改变
\begin{remark}
可以将Convolution1D看作Convolution2D的快捷版，对例子中（10，32）的信号进行1D卷积相当于对其进行卷积核为（filter\_length, 32）的2D卷积。
\end{remark}

\subsection{Conv2D层}
\begin{python}
keras.layers.convolutional.Conv2D(filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, dilation_rate=(1, 1), activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)
\end{python}
二维卷积层，即对图像的空域卷积。该层对二维输入进行滑动窗卷积，当使用该层作为第一层时，应提供input\_shape参数。例如input\_shape = (128,128,3)代表128*128的彩色RGB图像（data\_format='channels\_last'）
参数
\begin{itemize}
\item filters：卷积核的数目（即输出的维度）
\item kernel\_size：单个整数或由两个整数构成的list/tuple，卷积核的宽度和长度。如为单个整数，则表示在各个空间维度的相同长度。
\item strides：单个整数或由两个整数构成的list/tuple，为卷积的步长。如为单个整数，则表示在各个空间维度的相同步长。任何不为1的strides均与任何不为1的dilation\_rata均不兼容
\item padding：补0策略，为“valid”, “same” 。“valid”代表只进行有效的卷积，即对边界数据不处理。“same”代表保留边界处的卷积结果，通常会导致输出shape与输入shape相同。
\item activation：激活函数，为预定义的激活函数名（参考\nameref{ch:activation}），或逐元素（element-wise）的Theano函数。如果不指定该参数，将不会使用任何激活函数（即使用线性激活函数：a(x)=x）
\item dilation\_rate：单个整数或由两个个整数构成的list/tuple，指定dilated convolution中的膨胀比例。任何不为1的dilation\_rata均与任何不为1的strides均不兼容。
\item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表图像的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128的RGB图像为例，“channels\_first”应将数据组织为（3,128,128），而“channels\_last”应将数据组织为（128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\item use\_bias:布尔值，是否使用偏置项
\item kernel\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item bias\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item kernel\_regularizer：施加在权重上的正则项，为Regularizer对象
\item bias\_regularizer：施加在偏置向量上的正则项，为Regularizer对象
\item activity\_regularizer：施加在输出上的正则项，为Regularizer对象
\item kernel\_constraints：施加在权重上的约束项，为Constraints对象
\item bias\_constraints：施加在偏置上的约束项，为Constraints对象
\end{itemize}
输入shape
‘channels\_first’模式下，输入形如（samples,channels，rows，cols）的4D张量
‘channels\_last’模式下，输入形如（samples，rows，cols，channels）的4D张量

注意这里的输入shape指的是函数内部实现的输入shape，而非函数接口应指定的input\_shape，请参考下面提供的例子。

输出shape

‘channels\_first’模式下，为形如（samples，nb\_filter, new\_rows, new\_cols）的4D张量

‘channels\_last’模式下，为形如（samples，new\_rows, new\_cols，nb\_filter）的4D张量

输出的行列数可能会因为填充方法而改变

\subsection{SeparableConv2D层}
\begin{python}
keras.layers.convolutional.SeparableConv2D(filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, depth_multiplier=1, activation=None, use_bias=True, depthwise_initializer='glorot_uniform', pointwise_initializer='glorot_uniform', bias_initializer='zeros', depthwise_regularizer=None, pointwise_regularizer=None, bias_regularizer=None, activity_regularizer=None, depthwise_constraint=None, pointwise_constraint=None, bias_constraint=None)
\end{python}
该层是在深度方向上的可分离卷积。

可分离卷积首先按深度方向进行卷积（对每个输入通道分别卷积），然后逐点进行卷积，将上一步的卷积结果混合到输出通道中。参数depth\_multiplier控制了在depthwise卷积（第一步）的过程中，每个输入通道信号产生多少个输出通道。

直观来说，可分离卷积可以看做讲一个卷积核分解为两个小的卷积核，或看作Inception模块的一种极端情况。

当使用该层作为第一层时，应提供input\_shape参数。例如input\_shape = (3,128,128)代表128*128的彩色RGB图像

参数
\begin{itemize}
\item filters：卷积核的数目（即输出的维度）
\item kernel\_size：单个整数或由两个个整数构成的list/tuple，卷积核的宽度和长度。如为单个整数，则表示在各个空间维度的相同长度。
\item strides：单个整数或由两个整数构成的list/tuple，为卷积的步长。如为单个整数，则表示在各个空间维度的相同步长。任何不为1的strides均与任何不为1的dilation\_rata均不兼容
\item padding：补0策略，为“valid”, “same” 。“valid”代表只进行有效的卷积，即对边界数据不处理。“same”代表保留边界处的卷积结果，通常会导致输出shape与输入shape相同。
\item activation：激活函数，为预定义的激活函数名（参考\nameref{ch:activation}），或逐元素（element-wise）的Theano函数。如果不指定该参数，将不会使用任何激活函数（即使用线性激活函数：a(x)=x）
\item dilation\_rate：单个整数或由两个个整数构成的list/tuple，指定dilated convolution中的膨胀比例。任何不为1的dilation\_rata均与任何不为1的strides均不兼容。
\item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表图像的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128的RGB图像为例，“channels\_first”应将数据组织为（3,128,128），而“channels\_last”应将数据组织为（128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\item use\_bias:布尔值，是否使用偏置项
\item depth\_multiplier：在按深度卷积的步骤中，每个输入通道使用多少个输出通道
\item kernel\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item bias\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item depthwise\_regularizer：施加在按深度卷积的权重上的正则项，为Regularizer对象
\item pointwise\_regularizer：施加在按点卷积的权重上的正则项，为Regularizer对象
\item kernel\_regularizer：施加在权重上的正则项，为Regularizer对象
\item bias\_regularizer：施加在偏置向量上的正则项，为Regularizer对象
\item activity\_regularizer：施加在输出上的正则项，为Regularizer对象
\item kernel\_constraints：施加在权重上的约束项，为Constraints对象
\item bias\_constraints：施加在偏置上的约束项，为Constraints对象
\item depthwise\_constraint：施加在按深度卷积权重上的约束项，为Constraints对象
\item pointwise\_constraint施加在按点卷积权重的约束项，为Constraints对象
\item \end{itemize}
输入shape

‘channels\_first’模式下，输入形如（samples,channels，rows，cols）的4D张量

‘channels\_last’模式下，输入形如（samples，rows，cols，channels）的4D张量

注意这里的输入shape指的是函数内部实现的输入shape，而非函数接口应指定的input\_shape，请参考下面提供的例子。

输出shape

‘channels\_first’模式下，为形如（samples，nb\_filter, new\_rows, new\_cols）的4D张量

‘channels\_last’模式下，为形如（samples，new\_rows, new\_cols，nb\_filter）的4D张量

输出的行列数可能会因为填充方法而改变

\subsection{Conv2DTranspose层}
\begin{python}
keras.layers.convolutional.Conv2DTranspose(filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)
\end{python}
该层是转置的卷积操作（反卷积）。需要反卷积的情况通常发生在用户想要对一个普通卷积的结果做反方向的变换。例如，将具有该卷积层输出shape的tensor转换为具有该卷积层输入shape的tensor。同时保留与卷积层兼容的连接模式。

当使用该层作为第一层时，应提供input\_shape参数。例如input\_shape = (3,128,128)代表128*128的彩色RGB图像

参数
\begin{itemize}
    \item filters：卷积核的数目（即输出的维度）
    \item kernel\_size：单个整数或由两个个整数构成的list/tuple，卷积核的宽度和长度。如为单个整数，则表示在各个空间维度的相同长度。
    \item strides：单个整数或由两个整数构成的list/tuple，为卷积的步长。如为单个整数，则表示在各个空间维度的相同步长。任何不为1的strides均与任何不为1的dilation\_rata均不兼容
    \item padding：补0策略，为“valid”, “same” 。“valid”代表只进行有效的卷积，即对边界数据不处理。“same”代表保留边界处的卷积结果，通常会导致输出shape与输入shape相同。
    \item activation：激活函数，为预定义的激活函数名（参考\nameref{ch:activation}），或逐元素（element-wise）的Theano函数。如果不指定该参数，将不会使用任何激活函数（即使用线性激活函数：a(x)=x）
    \item dilation\_rate：单个整数或由两个个整数构成的list/tuple，指定dilated convolution中的膨胀比例。任何不为1的dilation\_rata均与任何不为1的strides均不兼容。
    \item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表图像的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128的RGB图像为例，“channels\_first”应将数据组织为（3,128,128），而“channels\_last”应将数据组织为（128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
    \item use\_bias:布尔值，是否使用偏置项
    \item kernel\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
    \item bias\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
    \item kernel\_regularizer：施加在权重上的正则项，为Regularizer对象
    \item bias\_regularizer：施加在偏置向量上的正则项，为Regularizer对象
    \item activity\_regularizer：施加在输出上的正则项，为Regularizer对象
    \item kernel\_constraints：施加在权重上的约束项，为Constraints对象
    \item bias\_constraints：施加在偏置上的约束项，为Constraints对象
\item \end{itemize}
输入shape

‘channels\_first’模式下，输入形如（samples,channels，rows，cols）的4D张量

‘channels\_last’模式下，输入形如（samples，rows，cols，channels）的4D张量

注意这里的输入shape指的是函数内部实现的输入shape，而非函数接口应指定的input\_shape，请参考下面提供的例子。

输出shape

‘channels\_first’模式下，为形如（samples，nb\_filter, new\_rows, new\_cols）的4D张量

‘channels\_last’模式下，为形如（samples，new\_rows, new\_cols，nb\_filter）的4D张量

输出的行列数可能会因为填充方法而改变

参考文献
\begin{itemize}
    \item \href{https://arxiv.org/pdf/1603.07285.pdf}{A guide to convolution arithmetic for deep learning}
    \item \href{http://deeplearning.net/software/theano_versions/dev/tutorial/conv_arithmetic.html#transposed-convolution-arithmetic}{Transposed convolution arithmetic}
    \item \href{http://www.matthewzeiler.com/wp-content/uploads/2017/07/cvpr2010.pdf}{Deconvolutional Networks}
\end{itemize}
\subsection{Conv3D层}
\begin{python}
keras.layers.convolutional.Conv3D(filters, kernel_size, strides=(1, 1, 1), padding='valid', data_format=None, dilation_rate=(1, 1, 1), activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)
\end{python}
三维卷积对三维的输入进行滑动窗卷积，当使用该层作为第一层时，应提供input\_shape参数。例如input\_shape = (3,10,128,128)代表对10帧128*128的彩色RGB图像进行卷积。数据的通道位置仍然有data\_format参数指定。

参数
\begin{itemize}
    \item filters：卷积核的数目（即输出的维度）
    \item kernel\_size：单个整数或由3个整数构成的list/tuple，卷积核的宽度和长度。如为单个整数，则表示在各个空间维度的相同长度。
    \item strides：单个整数或由3个整数构成的list/tuple，为卷积的步长。如为单个整数，则表示在各个空间维度的相同步长。任何不为1的strides均与任何不为1的dilation\_rata均不兼容
    \item padding：补0策略，为“valid”, “same” 。“valid”代表只进行有效的卷积，即对边界数据不处理。“same”代表保留边界处的卷积结果，通常会导致输出shape与输入shape相同。
    \item activation：激活函数，为预定义的激活函数名（参考\nameref{ch:activation}），或逐元素（element-wise）的Theano函数。如果不指定该参数，将不会使用任何激活函数（即使用线性激活函数：a(x)=x）
    \item dilation\_rate：单个整数或由3个个整数构成的list/tuple，指定dilated convolution中的膨胀比例。任何不为1的dilation\_rata均与任何不为1的strides均不兼容。
    \item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表数据的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128x128的数据为例，“channels\_first”应将数据组织为（3,128,128,128），而“channels\_last”应将数据组织为（128,128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
    \item use\_bias:布尔值，是否使用偏置项
    \item kernel\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
    \item bias\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
    \item kernel\_regularizer：施加在权重上的正则项，为Regularizer对象
    \item bias\_regularizer：施加在偏置向量上的正则项，为Regularizer对象
    \item activity\_regularizer：施加在输出上的正则项，为Regularizer对象
    \item kernel\_constraints：施加在权重上的约束项，为Constraints对象
    \item bias\_constraints：施加在偏置上的约束项，为Constraints对象
\end{itemize}
输入shape

‘channels\_first’模式下，输入应为形如（samples，channels，input\_dim1，input\_dim2, input\_dim3）的5D张量

‘channels\_last’模式下，输入应为形如（samples，input\_dim1，input\_dim2, input\_dim3，channels）的5D张量

这里的输入shape指的是函数内部实现的输入shape，而非函数接口应指定的input\_shape。

\subsection{Cropping1D层}
\begin{itemize}
    \item keras.layers.convolutional.Cropping1D(cropping=(1, 1))
\end{itemize}
在时间轴（axis1）上对1D输入（即时间序列）进行裁剪

参数
\begin{itemize}
\item cropping：长为2的tuple，指定在序列的首尾要裁剪掉多少个元素
\end{itemize}
输入shape

形如（samples，axis\_to\_crop，features）的3D张量
输出shape

形如（samples，cropped\_axis，features）的3D张量
Cropping2D层

keras.layers.convolutional.Cropping2D(cropping=((0, 0), (0, 0)), data\_format=None)
对2D输入（图像）进行裁剪，将在空域维度，即宽和高的方向上裁剪

参数
\begin{itemize}
\item cropping：长为2的整数tuple，分别为宽和高方向上头部与尾部需要裁剪掉的元素数
data\_format：字符串，“channels\_first”或“channels\_last”之一，代表图像的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128的RGB图像为例，“channels\_first”应将数据组织为（3,128,128），而“channels\_last”应将数据组织为（128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\end{itemize}
输入shape

形如（samples，depth, first\_axis\_to\_crop, second\_axis\_to\_crop）

输出shape

形如(samples, depth, first\_cropped\_axis, second\_cropped\_axis)的4D张量

\subsection{Cropping3D层}
\begin{itemize}
\item keras.layers.convolutional.Cropping3D(cropping=((1, 1), (1, 1), (1, 1)), data\_format=None)
\end{itemize}
对2D输入（图像）进行裁剪

参数
\begin{itemize}
    \item cropping：长为3的整数tuple，分别为三个方向上头部与尾部需要裁剪掉的元素数
data\_format：字符串，“channels\_first”或“channels\_last”之一，代表数据的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128x128的数据为例，“channels\_first”应将数据组织为（3,128,128,128），而“channels\_last”应将数据组织为（128,128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\end{itemize}
输入shape

形如 (samples, depth, first\_axis\_to\_crop, second\_axis\_to\_crop, third\_axis\_to\_crop)的5D张量

输出shape

形如(samples, depth, first\_cropped\_axis, second\_cropped\_axis, third\_cropped\_axis)的5D张量

\subsection{UpSampling1D层}
\begin{python}
keras.layers.convolutional.UpSampling1D(size=2)
\end{python}
在时间轴上，将每个时间步重复length次

参数
\begin{itemize}
    \item size：上采样因子
\end{itemize}
输入shape

形如（samples，steps，features）的3D张量
输出shape

形如（samples，upsampled\_steps，features）的3D张量
UpSampling2D层

keras.layers.convolutional.UpSampling2D(size=(2, 2), data\_format=None)
将数据的行和列分别重复size[0]和size[1]次

参数
\begin{itemize}
\item size：整数tuple，分别为行和列上采样因子
\item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表图像的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128的RGB图像为例，“channels\_first”应将数据组织为（3,128,128），而“channels\_last”应将数据组织为（128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\end{itemize}
输入shape

‘channels\_first’模式下，为形如（samples，channels, rows，cols）的4D张量

‘channels\_last’模式下，为形如（samples，rows, cols，channels）的4D张量

输出shape

‘channels\_first’模式下，为形如（samples，channels, upsampled\_rows, upsampled\_cols）的4D张量

‘channels\_last’模式下，为形如（samples，upsampled\_rows, upsampled\_cols，channels）的4D张量

UpSampling3D层
\begin{python}
keras.layers.convolutional.UpSampling3D(size=(2, 2, 2), data_format=None)
\end{python}
将数据的三个维度上分别重复size[0]、size[1]和size[2]次

本层目前只能在使用Theano为后端时可用

参数
\begin{itemize}
\item size：长为3的整数tuple，代表在三个维度上的上采样因子
\item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表数据的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128x128的数据为例，“channels\_first”应将数据组织为（3,128,128,128），而“channels\_last”应将数据组织为（128,128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\end{itemize}
输入shape

‘channels\_first’模式下，为形如（samples, channels, len\_pool\_dim1, len\_pool\_dim2, len\_pool\_dim3）的5D张量

‘channels\_last’模式下，为形如（samples, len\_pool\_dim1, len\_pool\_dim2, len\_pool\_dim3，channels, ）的5D张量

输出shape

‘channels\_first’模式下，为形如（samples, channels, dim1, dim2, dim3）的5D张量

‘channels\_last’模式下，为形如（samples, upsampled\_dim1, upsampled\_dim2, upsampled\_dim3,channels,）的5D张量

\subsection{ZeroPadding1D层}
\begin{itemize}
    \item keras.layers.convolutional.ZeroPadding1D(padding=1)
\end{itemize}
对1D输入的首尾端（如时域序列）填充0，以控制卷积以后向量的长度

参数
\begin{itemize}
\item padding：整数，表示在要填充的轴的起始和结束处填充0的数目，这里要填充的轴是轴1（第1维，第0维是样本数）
\end{itemize}
输入shape

形如（samples，axis\_to\_pad，features）的3D张量

输出shape

形如（samples，paded\_axis，features）的3D张量

\subsection{ZeroPadding2D层}
\begin{python}
keras.layers.convolutional.ZeroPadding2D(padding=(1, 1), data_format=None)
\end{python}
对2D输入（如图片）的边界填充0，以控制卷积以后特征图的大小

参数
\begin{itemize}
    \item padding：整数tuple，表示在要填充的轴的起始和结束处填充0的数目，这里要填充的轴是轴3和轴4（即在'th'模式下图像的行和列，在‘channels\_last’模式下要填充的则是轴2，3）
data\_format：字符串，“channels\_first”或“channels\_last”之一，代表图像的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128的RGB图像为例，“channels\_first”应将数据组织为（3,128,128），而“channels\_last”应将数据组织为（128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\end{itemize}
输入shape

‘channels\_first’模式下，形如（samples，channels，first\_axis\_to\_pad，second\_axis\_to\_pad）的4D张量

‘channels\_last’模式下，形如（samples，first\_axis\_to\_pad，second\_axis\_to\_pad, channels）的4D张量

输出shape

‘channels\_first’模式下，形如（samples，channels，first\_paded\_axis，second\_paded\_axis）的4D张量

‘channels\_last’模式下，形如（samples，first\_paded\_axis，second\_paded\_axis, channels）的4D张量

\subsection{ZeroPadding3D层}
\begin{itemize}
    \item keras.layers.convolutional.ZeroPadding3D(padding=(1, 1, 1), data\_format=None)
\end{itemize}
将数据的三个维度上填充0

本层目前只能在使用Theano为后端时可用

参数
\begin{itemize}
    \item padding：整数tuple，表示在要填充的轴的起始和结束处填充0的数目，这里要填充的轴是轴3，轴4和轴5，‘channels\_last’模式下则是轴2，3和4

    \item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表数据的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128x128的数据为例，“channels\_first”应将数据组织为（3,128,128,128），而“channels\_last”应将数据组织为（128,128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\end{itemize}
输入shape

‘channels\_first’模式下，为形如（samples, channels, first\_axis\_to\_pad，first\_axis\_to\_pad, first\_axis\_to\_pad,）的5D张量

‘channels\_last’模式下，为形如（samples, first\_axis\_to\_pad，first\_axis\_to\_pad, first\_axis\_to\_pad, channels）的5D张量

输出shape

‘channels\_first’模式下，为形如（samples, channels, first\_paded\_axis，second\_paded\_axis, third\_paded\_axis,）的5D张量

‘channels\_last’模式下，为形如（samples, len\_pool\_dim1, len\_pool\_dim2, len\_pool\_dim3，channels, ）的5D张量

\section{池化层}

\subsection{MaxPooling1D层}
\begin{python}
keras.layers.pooling.MaxPooling1D(pool_size=2, strides=None, padding='valid')
\end{python}
对时域1D信号进行最大值池化

参数
\begin{itemize}
    \item pool\_size：整数，池化窗口大小
    \item strides：整数或None，下采样因子，例如设2将会使得输出shape为输入的一半，若为None则默认值为pool\_size。
    \item padding：‘valid’或者‘same’
\end{itemize}
输入shape

形如（samples，steps，features）的3D张量
输出shape

形如（samples，downsampled\_steps，features）的3D张量
\subsection{MaxPooling2D层}
\begin{python}
keras.layers.pooling.MaxPooling2D(pool_size=(2, 2), strides=None, padding='valid', data_format=None)
\end{python}
为空域信号施加最大值池化

参数
\begin{itemize}
    \item pool\_size：整数或长为2的整数tuple，代表在两个方向（竖直，水平）上的下采样因子，如取（2，2）将使图片在两个维度上均变为原长的一半。为整数意为各个维度值相同且为该数字。
    \item strides：整数或长为2的整数tuple，或者None，步长值。
    \item border\_mode：‘valid’或者‘same’
    \item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表图像的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128的RGB图像为例，“channels\_first”应将数据组织为（3,128,128），而“channels\_last”应将数据组织为（128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\end{itemize}
输入shape

‘channels\_first’模式下，为形如（samples，channels, rows，cols）的4D张量

‘channels\_last’模式下，为形如（samples，rows, cols，channels）的4D张量

输出shape

‘channels\_first’模式下，为形如（samples，channels, pooled\_rows, pooled\_cols）的4D张量

‘channels\_last’模式下，为形如（samples，pooled\_rows, pooled\_cols，channels）的4D张量

\subsection{MaxPooling3D层}
\begin{python}
keras.layers.pooling.MaxPooling3D(pool_size=(2, 2, 2), strides=None, padding='valid', data_format=None)
\end{python}
为3D信号（空域或时空域）施加最大值池化

本层目前只能在使用Theano为后端时可用

参数
\begin{itemize}
\item pool\_size：整数或长为3的整数tuple，代表在三个维度上的下采样因子，如取（2，2，2）将使信号在每个维度都变为原来的一半长。
\item strides：整数或长为3的整数tuple，或者None，步长值。
\item padding：‘valid’或者‘same’
\item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表数据的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128x128的数据为例，“channels\_first”应将数据组织为（3,128,128,128），而“channels\_last”应将数据组织为（128,128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\end{itemize}
输入shape

‘channels\_first’模式下，为形如（samples, channels, len\_pool\_dim1, len\_pool\_dim2, len\_pool\_dim3）的5D张量

‘channels\_last’模式下，为形如（samples, len\_pool\_dim1, len\_pool\_dim2, len\_pool\_dim3，channels, ）的5D张量

输出shape

‘channels\_first’模式下，为形如（samples, channels, pooled\_dim1, pooled\_dim2, pooled\_dim3）的5D张量

‘channels\_last’模式下，为形如（samples, pooled\_dim1, pooled\_dim2, pooled\_dim3,channels,）的5D张量

\subsection{AveragePooling1D层}
\begin{itemize}
    \item keras.layers.pooling.AveragePooling1D(pool\_size=2, strides=None, padding='valid')
\end{itemize}
对时域1D信号进行平均值池化

参数
\begin{itemize}
    \item pool\_size：整数，池化窗口大小
    \item strides：整数或None，下采样因子，例如设2将会使得输出shape为输入的一半，若为None则默认值为pool\_size。
    \item padding：‘valid’或者‘same’
\end{itemize}
输入shape

形如（samples，steps，features）的3D张量
输出shape

形如（samples，downsampled\_steps，features）的3D张量
\subsection{AveragePooling2D层}
\begin{python}
keras.layers.pooling.AveragePooling2D(pool_size=(2, 2), strides=None, padding='valid', data_format=None)
\end{python}
为空域信号施加平均值池化

参数
\begin{itemize}
\item pool\_size：整数或长为2的整数tuple，代表在两个方向（竖直，水平）上的下采样因子，如取（2，2）将使图片在两个维度上均变为原长的一半。为整数意为各个维度值相同且为该数字。
\item strides：整数或长为2的整数tuple，或者None，步长值。
\item border\_mode：‘valid’或者‘same’
\item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表图像的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128的RGB图像为例，“channels\_first”应将数据组织为（3,128,128），而“channels\_last”应将数据组织为（128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\end{itemize}
输入shape

‘channels\_first’模式下，为形如（samples，channels, rows，cols）的4D张量

‘channels\_last’模式下，为形如（samples，rows, cols，channels）的4D张量

输出shape

‘channels\_first’模式下，为形如（samples，channels, pooled\_rows, pooled\_cols）的4D张量

‘channels\_last’模式下，为形如（samples，pooled\_rows, pooled\_cols，channels）的4D张量

\subsection{AveragePooling3D层}
\begin{python}
keras.layers.pooling.AveragePooling3D(pool_size=(2, 2, 2), strides=None, padding='valid', data_format=None)
\end{python}
为3D信号（空域或时空域）施加平均值池化

本层目前只能在使用Theano为后端时可用

参数
\begin{itemize}
\item pool\_size：整数或长为3的整数tuple，代表在三个维度上的下采样因子，如取（2，2，2）将使信号在每个维度都变为原来的一半长。
\item strides：整数或长为3的整数tuple，或者None，步长值。
\item padding：‘valid’或者‘same’
\item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表数据的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128x128的数据为例，“channels\_first”应将数据组织为（3,128,128,128），而“channels\_last”应将数据组织为（128,128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\item ‘channels\_first’模式下，为形如（samples, channels, len\_pool\_dim1, len\_pool\_dim2, len\_pool\_dim3）的5D张量
\item ‘channels\_last’模式下，为形如（samples, len\_pool\_dim1, len\_pool\_dim2, len\_pool\_dim3，channels, ）的5D张量
\end{itemize}
输出shape

‘channels\_first’模式下，为形如（samples, channels, pooled\_dim1, pooled\_dim2, pooled\_dim3）的5D张量

‘channels\_last’模式下，为形如（samples, pooled\_dim1, pooled\_dim2, pooled\_dim3,channels,）的5D张量

GlobalMaxPooling1D层

keras.layers.pooling.GlobalMaxPooling1D()
对于时间信号的全局最大池化

输入shape

形如（samples，steps，features）的3D张量
输出shape

形如(samples, features)的2D张量
\subsection{GlobalAveragePooling1D层}
\begin{python}
keras.layers.pooling.GlobalAveragePooling1D()
\end{python}
为时域信号施加全局平均值池化

输入shape

形如（samples，steps，features）的3D张量
输出shape

形如(samples, features)的2D张量
\subsection{GlobalMaxPooling2D层}
\begin{python}
keras.layers.pooling.GlobalMaxPooling2D(dim\_ordering='default')
\end{python}
为空域信号施加全局最大值池化

参数
\begin{itemize}
\item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表图像的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128的RGB图像为例，“channels\_first”应将数据组织为（3,128,128），而“channels\_last”应将数据组织为（128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\end{itemize}
输入shape

‘channels\_first’模式下，为形如（samples，channels, rows，cols）的4D张量

‘channels\_last’模式下，为形如（samples，rows, cols，channels）的4D张量

输出shape

形如(nb\_samples, channels)的2D张量

\subsection{GlobalAveragePooling2D层}
\begin{python}
keras.layers.pooling.GlobalAveragePooling2D(dim_ordering='default')
\end{python}
为空域信号施加全局平均值池化

参数
\begin{itemize}
\item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表图像的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128的RGB图像为例，“channels\_first”应将数据组织为（3,128,128），而“channels\_last”应将数据组织为（128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\end{itemize}
输入shape

‘channels\_first’模式下，为形如（samples，channels, rows，cols）的4D张量

‘channels\_last’模式下，为形如（samples，rows, cols，channels）的4D张量

输出shape

形如(nb\_samples, channels)的2D张量
\section{局部连接层LocallyConnceted}

\subsection{LocallyConnected1D层}
\begin{python}
keras.layers.local.LocallyConnected1D(filters, kernel_size, strides=1, padding='valid', data_format=None, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)
\end{python}
LocallyConnected1D层与Conv1D工作方式类似，唯一的区别是不进行权值共享。即施加在不同输入位置的滤波器是不一样的。

参数
\begin{itemize}
\item filters：卷积核的数目（即输出的维度）
\item kernel\_size：整数或由单个整数构成的list/tuple，卷积核的空域或时域窗长度
\item strides：整数或由单个整数构成的list/tuple，为卷积的步长。任何不为1的strides均与任何不为1的dilation\_rata均不兼容
\item padding：补0策略，目前仅支持valid（大小写敏感），same可能会在将来支持。
\item activation：激活函数，为预定义的激活函数名（参考\nameref{ch:activation}），或逐元素（element-wise）的Theano函数。如果不指定该参数，将不会使用任何激活函数（即使用线性激活函数：a(x)=x）
\item dilation\_rate：整数或由单个整数构成的list/tuple，指定dilated convolution中的膨胀比例。任何不为1的dilation\_rata均与任何不为1的strides均不兼容。
\item use\_bias:布尔值，是否使用偏置项
\item kernel\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item bias\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item kernel\_regularizer：施加在权重上的正则项，为Regularizer对象
\item bias\_regularizer：施加在偏置向量上的正则项，为Regularizer对象
\item activity\_regularizer：施加在输出上的正则项，为Regularizer对象
\item kernel\_constraints：施加在权重上的约束项，为Constraints对象
\item bias\_constraints：施加在偏置上的约束项，为Constraints对象
\end{itemize}
输入shape

形如（samples，steps，input\_dim）的3D张量

输出shape

形如（samples，new\_steps，nb\_filter）的3D张量，因为有向量填充的原因，steps的值会改变

\subsection{LocallyConnected2D层}
\begin{python}
keras.layers.local.LocallyConnected2D(filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None)
\end{python}
LocallyConnected2D层与Convolution2D工作方式类似，唯一的区别是不进行权值共享。即施加在不同输入patch的滤波器是不一样的，当使用该层作为模型首层时，需要提供参数input\_dim或input\_shape参数。参数含义参考Convolution2D。

参数
\begin{itemize}
\item filters：卷积核的数目（即输出的维度）
\item kernel\_size：单个整数或由两个整数构成的list/tuple，卷积核的宽度和长度。如为单个整数，则表示在各个空间维度的相同长度。
\item strides：单个整数或由两个整数构成的list/tuple，为卷积的步长。如为单个整数，则表示在各个空间维度的相同步长。
\item padding：补0策略，目前仅支持valid（大小写敏感），same可能会在将来支持。
\item activation：激活函数，为预定义的激活函数名（参考\nameref{ch:activation}），或逐元素（element-wise）的Theano函数。如果不指定该参数，将不会使用任何激活函数（即使用线性激活函数：a(x)=x）
\item data\_format：字符串，“channels\_first”或“channels\_last”之一，代表图像的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channels\_last”对应原本的“tf”，“channels\_first”对应原本的“th”。以128x128的RGB图像为例，“channels\_first”应将数据组织为（3,128,128），而“channels\_last”应将数据组织为（128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channels\_last”。
\item use\_bias:布尔值，是否使用偏置项
\item kernel\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item bias\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item kernel\_regularizer：施加在权重上的正则项，为Regularizer对象
\item bias\_regularizer：施加在偏置向量上的正则项，为Regularizer对象
\item activity\_regularizer：施加在输出上的正则项，为Regularizer对象
\item kernel\_constraints：施加在权重上的约束项，为Constraints对象
\item bias\_constraints：施加在偏置上的约束项，为Constraints对象
\end{itemize}
输入shape

‘channels\_first’模式下，输入形如（samples,channels，rows，cols）的4D张量

‘channels\_last’模式下，输入形如（samples，rows，cols，channels）的4D张量

注意这里的输入shape指的是函数内部实现的输入shape，而非函数接口应指定的input\_shape，请参考下面提供的例子。

输出shape

‘channels\_first’模式下，为形如（samples，nb\_filter, new\_rows, new\_cols）的4D张量

‘channels\_last’模式下，为形如（samples，new\_rows, new\_cols，nb\_filter）的4D张量

输出的行列数可能会因为填充方法而改变

例子
\begin{python}
# apply a 3x3 unshared weights convolution with 64 output filters on a 32x32 image
# with `data_format="channels_last"`:
model = Sequential()
model.add(LocallyConnected2D(64, (3, 3), input_shape=(32, 32, 3)))
# now model.output_shape == (None, 30, 30, 64)
# notice that this layer will consume (30*30)*(3*3*3*64) + (30*30)*64 parameters

# add a 3x3 unshared weights convolution on top, with 32 output filters:
model.add(LocallyConnected2D(32, (3, 3)))
# now model.output_shape == (None, 28, 28, 32)
\end{python}
\section{循环层Recurrent}

Recurrent层
\begin{python}
keras.layers.recurrent.Recurrent(return_sequences=False, go_backwards=False, stateful=False, unroll=False, implementation=0)
\end{python}
这是循环层的抽象类，请不要在模型中直接应用该层（因为它是抽象类，无法实例化任何对象）。请使用它的子类LSTM，GRU或SimpleRNN。

所有的循环层（LSTM,GRU,SimpleRNN）都服从本层的性质，并接受本层指定的所有关键字参数。

参数
\begin{itemize}
\item weights：numpy array的list，用以初始化权重。该list形如[(input\_dim, output\_dim),(output\_dim, output\_dim),(output\_dim,)]
\item return\_sequences：布尔值，默认False，控制返回类型。若为True则返回整个序列，否则仅返回输出序列的最后一个输出
\item go\_backwards：布尔值，默认为False，若为True，则逆向处理输入序列并返回逆序后的序列
\item stateful：布尔值，默认为False，若为True，则一个batch中下标为i的样本的最终状态将会用作下一个batch同样下标的样本的初始状态。
\item unroll：布尔值，默认为False，若为True，则循环层将被展开，否则就使用符号化的循环。当使用TensorFlow为后端时，循环网络本来就是展开的，因此该层不做任何事情。层展开会占用更多的内存，但会加速RNN的运算。层展开只适用于短序列。
\item implementation：0，1或2， 若为0，则RNN将以更少但是更大的矩阵乘法实现，因此在CPU上运行更快，但消耗更多的内存。如果设为1，则RNN将以更多但更小的矩阵乘法实现，因此在CPU上运行更慢，在GPU上运行更快，并且消耗更少的内存。如果设为2（仅LSTM和GRU可以设为2），则RNN将把输入门、遗忘门和输出门合并为单个矩阵，以获得更加在GPU上更加高效的实现。注意，RNN dropout必须在所有门上共享，并导致正则效果性能微弱降低。
\item input\_dim：输入维度，当使用该层为模型首层时，应指定该值（或等价的指定input\_shape)
\item input\_length：当输入序列的长度固定时，该参数为输入序列的长度。当需要在该层后连接Flatten层，然后又要连接Dense层时，需要指定该参数，否则全连接的输出无法计算出来。注意，如果循环层不是网络的第一层，你需要在网络的第一层中指定序列的长度（通过input\_shape指定）。
\end{itemize}
输入shape

形如（samples，timesteps，input\_dim）的3D张量

输出shape

如果return\_sequences=True：返回形如（samples，timesteps，output\_dim）的3D张量

否则，返回形如（samples，output\_dim）的2D张量

例子
\begin{python}
# as the first layer in a Sequential model
model = Sequential()
model.add(LSTM(32, input_shape=(10, 64)))
# now model.output_shape == (None, 32)
# note: `None` is the batch dimension.

# the following is identical:
model = Sequential()
model.add(LSTM(32, input_dim=64, input_length=10))

# for subsequent layers, no need to specify the input size:
         model.add(LSTM(16))

# to stack recurrent layers, you must use return_sequences=True
# on any recurrent layer that feeds into another recurrent layer.
# note that you only need to specify the input size on the first layer.
model = Sequential()
model.add(LSTM(64, input_dim=64, input_length=10, return_sequences=True))
model.add(LSTM(32, return_sequences=True))
model.add(LSTM(10))
\end{python}
指定RNN初始状态的注意事项

可以通过设置initial\_state用符号式的方式指定RNN层的初始状态。即，initial\_stat的值应该为一个tensor或一个tensor列表，代表RNN层的初始状态。

也可以通过设置reset\_states参数用数值的方法设置RNN的初始状态，状态的值应该为numpy数组或numpy数组的列表，代表RNN层的初始状态。

屏蔽输入数据（Masking）

循环层支持通过时间步变量对输入数据进行Masking，如果想将输入数据的一部分屏蔽掉，请使用Embedding层并将参数mask\_zero设为True。

使用状态RNN的注意事项

可以将RNN设置为‘stateful’，意味着由每个batch计算出的状态都会被重用于初始化下一个batch的初始状态。状态RNN假设连续的两个batch之中，相同下标的元素有一一映射关系。

要启用状态RNN，请在实例化层对象时指定参数stateful=True，并在Sequential模型使用固定大小的batch：通过在模型的第一层传入batch\_size=(...)和input\_shape来实现。在函数式模型中，对所有的输入都要指定相同的batch\_size。

如果要将循环层的状态重置，请调用.reset\_states()，对模型调用将重置模型中所有状态RNN的状态。对单个层调用则只重置该层的状态。

\subsection{SimpleRNN层}
\begin{python}
keras.layers.recurrent.SimpleRNN(units, activation='tanh', use_bias=True, kernel_initializer='glorot_uniform', recurrent_initializer='orthogonal', bias_initializer='zeros', kernel_regularizer=None, recurrent_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, recurrent_constraint=None, bias_constraint=None, dropout=0.0, recurrent_dropout=0.0)
\end{python}
全连接RNN网络，RNN的输出会被回馈到输入

参数
\begin{itemize}
\item units：输出维度
\item activation：激活函数，为预定义的激活函数名,参考\nameref{ch:activation}
\item use\_bias: 布尔值，是否使用偏置项
\item kernel\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item recurrent\_initializer：循环核的初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item bias\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item kernel\_regularizer：施加在权重上的正则项，为Regularizer对象
\item bias\_regularizer：施加在偏置向量上的正则项，为Regularizer对象
\item recurrent\_regularizer：施加在循环核上的正则项，为Regularizer对象
\item activity\_regularizer：施加在输出上的正则项，为Regularizer对象
\item kernel\_constraints：施加在权重上的约束项，为Constraints对象
\item recurrent\_constraints：施加在循环核上的约束项，为Constraints对象
\item bias\_constraints：施加在偏置上的约束项，为Constraints对象
\item dropout：0~1之间的浮点数，控制输入线性变换的神经元断开比例
\item recurrent\_dropout：0~1之间的浮点数，控制循环状态的线性变换的神经元断开比例
\end{itemize}
参考文献
\begin{itemize}
\item \href{https://arxiv.org/pdf/1512.05287.pdf}{A Theoretically Grounded Application of Dropout in Recurrent Neural Networks}
\end{itemize}
\subsection{GRU层}
\begin{python}
keras.layers.recurrent.GRU(units, activation='tanh', recurrent_activation='hard_sigmoid', use_bias=True, kernel_initializer='glorot_uniform', recurrent_initializer='orthogonal', bias_initializer='zeros', kernel_regularizer=None, recurrent_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, recurrent_constraint=None, bias_constraint=None, dropout=0.0, recurrent_dropout=0.0)
\end{python}
门限循环单元（详见参考文献）

参数
\begin{itemize}
\item units：输出维度
\item activation：激活函数，为预定义的激活函数名（参考\nameref{ch:activation}）
\item use\_bias: 布尔值，是否使用偏置项
\item kernel\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item recurrent\_initializer：循环核的初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item bias\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item kernel\_regularizer：施加在权重上的正则项，为Regularizer对象
\item bias\_regularizer：施加在偏置向量上的正则项，为Regularizer对象
\item recurrent\_regularizer：施加在循环核上的正则项，为Regularizer对象
\item activity\_regularizer：施加在输出上的正则项，为Regularizer对象
\item kernel\_constraints：施加在权重上的约束项，为Constraints对象
\item recurrent\_constraints：施加在循环核上的约束项，为Constraints对象
\item bias\_constraints：施加在偏置上的约束项，为Constraints对象
\item dropout：0~1之间的浮点数，控制输入线性变换的神经元断开比例
\item recurrent\_dropout：0~1之间的浮点数，控制循环状态的线性变换的神经元断开比例
\end{itemize}
参考文献
\begin{itemize}
\item \href{http://www.aclweb.org/anthology/W14-4012}{On the Properties of Neural Machine Translation: Encoder–Decoder Approaches}
\item \href{https://arxiv.org/pdf/1412.3555v1.pdf}{Empirical Evaluation of Gated Recurrent Neural Networks on Sequence Modeling}
\item \href{https://arxiv.org/pdf/1512.05287.pdf}{A Theoretically Grounded Application of Dropout in Recurrent Neural Networks}
\end{itemize}
\subsection{LSTM层}
\begin{python}
keras.layers.recurrent.LSTM(units, activation='tanh', recurrent_activation='hard_sigmoid', use_bias=True, kernel_initializer='glorot_uniform', recurrent_initializer='orthogonal', bias_initializer='zeros', unit_forget_bias=True, kernel_regularizer=None, recurrent_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, recurrent_constraint=None, bias_constraint=None, dropout=0.0, recurrent_dropout=0.0)
\end{python}
Keras长短期记忆模型，关于此算法的详情，请参考本教程
参数
\begin{itemize}
\item units：输出维度
\item activation：激活函数，为预定义的激活函数名（参考\nameref{ch:activation}）
\item recurrent\_activation: 为循环步施加的激活函数（参考\nameref{ch:activation}）
\item use\_bias: 布尔值，是否使用偏置项
\item kernel\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item recurrent\_initializer：循环核的初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item bias\_initializer：权值初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item kernel\_regularizer：施加在权重上的正则项，为Regularizer对象
\item bias\_regularizer：施加在偏置向量上的正则项，为Regularizer对象
\item recurrent\_regularizer：施加在循环核上的正则项，为Regularizer对象
\item activity\_regularizer：施加在输出上的正则项，为Regularizer对象
\item kernel\_constraints：施加在权重上的约束项，为Constraints对象
\item recurrent\_constraints：施加在循环核上的约束项，为Constraints对象
\item bias\_constraints：施加在偏置上的约束项，为Constraints对象
\item dropout：0~1之间的浮点数，控制输入线性变换的神经元断开比例
\item recurrent\_dropout：0~1之间的浮点数，控制循环状态的线性变换的神经元断开比例
\end{itemize}
参考文献
\begin{itemize}
\item \href{https://arxiv.org/pdf/1512.05287.pdf}{Long short-term memory（original 1997 paper）}
\item \href{http://www.mitpressjournals.org/doi/abs/10.1162/089976600300015015?journalCode=neco}{Learning to forget: Continual prediction with LSTM}
\item \href{http://www.cs.toronto.edu/~graves/preprint.pdf}{Supervised sequence labelling with recurrent neural networks}
\item \href{https://arxiv.org/pdf/1512.05287.pdf}{A Theoretically Grounded Application of Dropout in Recurrent Neural Networks}
\end{itemize}
\section{嵌入层 Embedding}

Embedding层
\begin{python}
keras.layers.embeddings.Embedding(
input_dim, output_dim,
embeddings_initializer='uniform',
embeddings_regularizer=None,
activity_regularizer=None,
embeddings_constraint=None,
mask_zero=False,
input_length=None)
\end{python}
嵌入层将正整数（下标）转换为具有固定大小的向量，如[[4],[20]]->[[0.25,0.1],[0.6,-0.2]]

Embedding层只能作为模型的第一层

参数
\begin{itemize}
\item input\_dim：大于0的整数，词汇的大小，即输入数据最大下标+1
\item output\_dim：大于等于0的整数，代表全连接嵌入的维度
\item embeddings\_initializer: 嵌入矩阵的初始化方法，为预定义初始化方法名的字符串，或用于初始化权重的初始化器。参考\nameref{ch:初始化方法}
\item embeddings\_regularizer: 嵌入矩阵的正则项，为Regularizer对象
\item embeddings\_constraint: 嵌入矩阵的约束项，为Constraints对象
\item mask\_zero：布尔值，确定是否将输入中的‘0’看作是应该被忽略的‘填充’（padding）值，该参数在使用递归层处理变长输入时有用。设置为True的话，模型中后续的层必须都支持masking，否则会抛出异常。如果该值为True，则下标0在字典中不可用，input\_dim应设置为|vocabulary| + 2。
\item input\_length：当输入序列的长度固定时，输入序列的长度，当它为常数时，如果你想连接`Flatten`然后'Dense',这个参数要求被提供。
\end{itemize}
输入shape

形如（samples，sequence\_length）的2D张量

输出shape

形如(samples, sequence\_length, output\_dim)的3D张量

例子
\begin{python}
model = Sequential()
model.add(Embedding(1000, 64, input_length=10))
# the model will take as input an integer matrix of size (batch, input_length).
# the largest integer (i.e. word index) in the input should be no larger than 999 (vocabulary size).
# now model.output_shape == (None, 10, 64), where None is the batch dimension.

input_array = np.random.randint(1000, size=(32, 10))

model.compile('rmsprop', 'mse')
output_array = model.predict(input_array)
assert output_array.shape == (32, 10, 64)
\end{python}
参考文献
\begin{itemize}
\item \href{https://arxiv.org/pdf/1512.05287}{A Theoretically Grounded Application of Dropout in Recurrent Neural Networks}
\end{itemize}
\section{Merge层}

一个Merge层可以用来融合一个tensor列表为一个单独的tensor。
\begin{python}
model1 = Sequential()
model1.add(Dense(32,input_dim=32))
model2 = Sequential()
model2.add(Dense(32,input_dim=32))
merged_model = Sequential()
merged_model.add(Merge([model1,model2],mode='concat',concat_axis=1))
\end{python}
参数

\begin{itemize}
        \item layers:可以是一个Keras tensor或者一个layer实例列表。必须大于一个layer/tensor
        \item mode:字符串或者lambda/function。如果字符串，必须是下面中的一个:`sum`,`mul`,`concat`,`ave`,`cos`,`dot`,`max`如果lambda/function,将得到一个tensor列表返回一个tensor。
        \item cocat\_axis:整数，axis用在`concat`模式
        \item dot\_axes:正整数或者整数列表，axes用在`dot`或者`cos`模式
        \item output\_shape:可以是一个整数元祖或者lambda/function计算`output\_shape`(仅仅是labda/function融合模式)，如果参数是一个元祖，它应该是期望的输出形状，不包含批的大小(和layers中的`input\_shape`参数规则相同)，如果参数被调用，它应该得到一乐元祖列表作为输入(1:1映射输入tensors)返回一个形状的元祖，包含批的大小(和`compute\_output\_shape`同样规则)
        \item node\_indices:包含每个层输出节点索引的证书列表虚心向(一些输入层有多个输出节点)如果不提供将默认为一个数组0
        \item\_indices:融合的输出Tensor索引列表()在一些输入层节点转化多个tensor
        \item output\_mask:掩模或者lambda/function计算输出掩模（仅仅是如果融合模式是一个lambda/function）.如果是后者他应该接受掩模列表返回一个掩模。

\end{itemize}
\subsection{Add}
\pythoninline{keras.layers.Add()}
添加一个输入列表它将接受一个tensor列表，返回一个tensor(相同形状)
\begin{python}
import keras
input1 = keras.layers.Input(shape=(16,))
x1 = keras.layers.Dense(8,activation='relu')(input1)
input2 = keras.layers.Input(shape=(32,))
x2 = keras.layers.Dense(8,activation='relu')(input2)
added = keras.layers.Dense(4)(added)
model = keras.models.Model(inputs=[input1,input2],outputs=out)
\end{python}
\subsection{Subtract}
\pythoninline{keras.layers.Subtract()}
输入相减层。
它接收size为2的tensor列表，两个元素形状相同，返回一个tensor，(inputs[0]-inputs[1]和原来的元素有相同的形状)
\begin{python}
import keras
input1 = keras.layers.Input(shape=(16,))
x1 = keras.layers.Dense(8,activation='relu')(input1)
input2 = keras.layers.Input(shape=(32,))
x2 = keras.layers.Dense(8,activation='relu'(input2))
subtracted = keras.layers.Subtract()([x1, x2])

out = keras.layers.Dense(4)(subtracted)
model = keras.models.Model(inputs=[input1, input2], outputs=out)
\end{python}
\subsection{Multiply}
\pythoninline{ keras.layers.Multiply()}

对输入列表按元素相乘，并返回它们的逐元素积的张量，shape不变。

\subsection{Average}
\pythoninline{keras.layers.Average()}
该层接收一个列表的相同shape张量，并返回它们的逐元素均值，shape不变。

\subsection{Maximum}
\pythoninline{keras.layers.Maximum()}
该层接收一个相同shape张量的列表，并返回它们的逐元素最大值，shape不变。

\subsection{Concatenate}
\pythoninline{keras.layers.Concatenate(axis=-1)}
该层接收一个相同shape的张量列表，并返回它们的按照给定轴相接构成的向量。

\begin{itemize}
    \item axis: 沿着axis制定的轴拼接
    \item **kwargs: 标准的Layer关键字参数
\end{itemize}
\pythoninline{keras.layers.Dot(axes, normalize=False)}
算两个tensor中样本的张量乘积。例如，如果两个张量a和b的shape都为（batch\_size, n），则输出为形如（batch\_size,1）的张量，结果张量每个batch的数据都是a[i,:]和b[i,:]的矩阵（向量）点积。

参数
\begin{itemize}
    \item axes: 整数或整数的tuple，执行乘法的轴。
    \item normalize: 布尔值，是否沿执行成绩的轴做L2规范化，如果设为True，那么乘积的输出是两个样本的余弦相似性。
    \item **kwargs: 普通的Layer关键字参数
\end{itemize}
\subsection{add}
Add层的函数接口

参数：
\begin{itemize}
    \item inputs: 长度至少为2的张量列表A
    \item **kwargs: 标准的Layer关键字参数
    \item[返回值] 输入列表Tensor的和
\end{itemize}
\begin{python}
import keras
input1 = keras.layers.Input(shape=(16,))
x1 = keras.layers.Dense(8,activation='relu')(input1)
input2 = keras.layers.Input(shape=(32,))
x2 = keras.layers.Dense(8, activation='relu')(input2)
added = keras.layers.add([x1, x2])

out = keras.layers.Dense(4)(added)
model = keras.models.Model(inputs=[input1, input2], outputs=out)

\end{python}
\subsection{subtract}
\pythoninline{keras.layers.subtract(inputs)}
Subtract层的函数接口
参数
\begin{itemize}
        \item inputs:tensor列表，长度为2
        \item **kwargs:标准层与案件自参数
        \item[返回]：输入差的tensor
\end{itemize}
\subsection{multiply}

\begin{python}
import keras

input1 = keras.layers.Input(shape=(16,))
x1 = keras.layers.Dense(8, activation='relu')(input1)
input2 = keras.layers.Input(shape=(32,))
x2 = keras.layers.Dense(8, activation='relu')(input2)
subtracted = keras.layers.subtract([x1, x2])

out = keras.layers.Dense(4)(subtracted)
model = keras.models.Model(inputs=[input1, input2], outputs=out)
\end{python}
\subsection{multiply}
\pythoninline{keras.layers.multiply(inputs)}
\begin{itemize}
    \item inputs: 长度至少为2的张量列表
    \item  **kwargs: 普通的Layer关键字参数
    \item[返回值]输入列表张量之逐元素积
\end{itemize}
\subsection{average}
\pythoninline{keras.layers.average(inputs)}

参数：
\begin{itemize}
\item inputs: 长度至少为2的张量列表
\item **kwargs: 标准的Layer关键字参数
\item[返回值]输入列表张量之逐元素均值
\end{itemize}
\subsection{maximum}
\pythoninline{keras.layers.maxmum(inputs)}
参数：
\begin{itemize}
\item inputs: 长度至少为2的张量列表
\item **kwargs: 标准的Layer关键字参数
\item[返回值]输入列表张量之逐元素均值
\end{itemize}

\subsection{concatenate}
\pythoninline{keras.layers.concatenate(inputs,axis=-1)}
Concatenate的函数接口

参数
\begin{itemize}
\item inputs: 长度至少为2的张量列
\item axis: 相接的轴
\item **kwargs: 普通的Layer关键字参数
\end{itemize}
\subsection{dot}
\pythoninline{keras.layers.dot(inputs,axes,nornalize=False)}
Dot层的函数接口
参数
\begin{itemize}
\item inputs: 长度至少为2的张量列
\item axes: 整数或整数的tuple，执行乘法的轴。
\item normalize: 布尔值，是否沿执行成绩的轴做L2规范化，如果设为True，那么乘积的输出是两个样本的余弦相似性。
\item **kwargs: 普通的Layer关键字参数
\end{itemize}
\section{Advanced Activation}

\subsection{LeakyReLU层}
\begin{python}
keras.layers.LeakyReLU(alpha=0.3)
\end{python}
LeakyRelU是修正线性单元（Rectified Linear Unit，ReLU）的特殊版本，当不激活时，LeakyReLU仍然会有非零输出值，从而获得一个小梯度，避免ReLU可能出现的神经元“死亡”现象。即，f(x)=alpha * x for x < 0, f(x) = x for x>=0
参数
\begin{itemize}
\item alpha：大于0的浮点数，代表激活函数图像中第三象限线段的斜率
\end{itemize}
输入shape任意，当使用该层为模型首层时需指定input\_shape参数

输出shape与输入相同

参考文献

\href{https://web.stanford.edu/~awni/papers/relu\_hybrid\_icml2013\_final.pdf}{Rectifier Nonlinearities Improve Neural Network Acoustic Models}
%
\subsection{PReLU层}
\begin{python}
keras.layers.PReLU(alpha_initializer='zeros', alpha_regularizer=None, alpha_constraint=None, shared_axes=None)
\end{python}
该层为参数化的ReLU（Parametric ReLU），表达式是：f(x) = alpha * x for x < 0,  f(x) = x for x>=0，此处的alpha为一个与x shape相同的可学习的参数数组。

参数
\begin{itemize}
\item alpha\_initializer：alpha的初始化函数
\item alpha\_regularizer：alpha的正则项
\item alpha\_constraint：alpha的约束项
\item shared\_axes：该参数指定的轴将共享同一组科学系参数，例如假如输入特征图是从2D卷积过来的，具有形如(batch, height, width, channels)这样的shape，则或许你会希望在空域共享参数，这样每个filter就只有一组参数，设定shared\_axes=[1,2]可完成该目标
\end{itemize}
输入shape任意，当使用该层为模型首层时需指定input\_shape参数

输出shape与输入相同

参考文献

\href{http://arxiv.org/pdf/1502.01852v1.pdf}{Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification}
\subsection{ELU层}
\begin{python}
keras.layers.ELU(alpha=1.0)
\end{python}
ELU层是指数线性单元（Exponential Linera Unit），表达式为： 该层为参数化的ReLU（Parametric ReLU），表达式是：f(x) = alpha * (exp(x) - 1.) for x < 0, f(x) = x for x>=0

参数
\begin{itemize}
\item alpha：控制负因子的参数
\end{itemize}
输入shape任意，当使用该层为模型首层时需指定input\_shape(整数元祖，不包含samples的轴)参数

输出shape与输入相同

参考文献

\href{https://arxiv.org/pdf/1511.07289v1.pdf}{Fast and Accurate Deep Network Learning by Exponential Linear Units (ELUs)}
\begin{python}
keras.layers.ThresholdedReLU(theta=1.0)
\end{python}
该层是带有门限的ReLU，表达式是：f(x) = x for x > theta,f(x) = 0 otherwise

参数
\begin{itemize}
\item theata：大或等于0的浮点数，激活门限位置
\end{itemize}
输入shape任意，当使用该层为模型首层时需指定input\_shape(整数元祖，不包含samples轴)参数

输出shape与输入相同

参考文献

\href{http://arxiv.org/pdf/1402.3337.pdf}{Zero-Bias Autoencoders and the Benefits of Co-Adapting Features}
\section{（批）规范化BatchNormalization}

BatchNormalization层
\begin{python}
keras.layers.BatchNormalization(axis=-1, momentum=0.99, epsilon=0.001, center=True, scale=True, beta_initializer='zeros', gamma_initializer='ones', moving_mean_initializer='zeros', moving_variance_initializer='ones', beta_regularizer=None, gamma_regularizer=None, beta_constraint=None, gamma_constraint=None)
\end{python}
该层在每个batch上将前一层的激活值重新规范化，即使得其输出数据的均值接近0，其标准差接近1

参数
\begin{itemize}
\item axis: 整数，指定要规范化的轴，通常为特征轴。例如在进行data\_format="channels\_first的2D卷积后，一般会在BatchNormalization设axis=1。
\item momentum: 滑动平均的动量
\item epsilon：大于0的小浮点数，用于防止除0错误
\item center: 若设为True，将会将beta作为偏置加上去，否则忽略参数beta
\item scale: 若设为True，则会乘以gamma，否则不使用gamma。当下一层是线性的时，可以设False，因为scaling的操作将被下一层执行。
\item beta\_initializer：beta权重的初始方法
\item gamma\_initializer: gamma的初始化方法
\item moving\_mean\_initializer: 滑动平均的初始化方法
\item moving\_variance\_initializer: 滑动方差的初始化方法
\item beta\_regularizer: 可选的beta正则
\item gamma\_regularizer: 可选的gamma正则
\item beta\_constraint: 可选的beta约束
\item gamma\_constraint: 可选的gamma约束
\end{itemize}
输入shape任意，当使用本层为模型首层时，指定input\_shape参数时有意义。

输出shape与输入shape相同

参考文献
\begin{itemize}
    \item \href{http://arxiv.org/pdf/1502.03167v3.pdf}{Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift}
\end{itemize}
\begin{quote}
BN层的作用
\begin{enumerate}
\item 加速收敛
\item 控制过拟合，可以少用或不用Dropout和正则
\item 降低网络对初始化权重不敏感
\item 允许使用较大的学习率
\end{enumerate}
\end{quote}
\section{噪声层Noise}

GaussianNoise层
\begin{python}
keras.layers.GaussianNoise(stddev)
\end{python}
为数据施加0均值，标准差为stddev的加性高斯噪声。该层在克服过拟合时比较有用，你可以将它看作是随机的数据提升。高斯噪声是需要对输入数据进行破坏时的自然选择。

因为这是一个起正则化作用的层，该层只在训练时才有效。

参数
\begin{itemize}
    \item stddev：浮点数，代表要产生的高斯噪声标准差
\end{itemize}
输入shape任意，当使用该层为模型首层时需指定input\_shape参数

输出shape与输入相同

\subsection{GaussianDropout层}
\begin{python}
keras.layers.GaussianDropout(rate)
\end{python}
为层的输入施加以1为均值，标准差为sqrt(rate/(1-rate)的乘性高斯噪声

因为这是一个起正则化作用的层，该层只在训练时才有效。

参数
\begin{itemize}
    \item rate：浮点数，断连概率，与Dropout层相同
\end{itemize}
输入shape任意，当使用该层为模型首层时需指定input\_shape参数

输出shape与输入相同

参考文献
\href{http://www.cs.toronto.edu/~rsalakhu/papers/srivastava14a.pdf}{Dropout: A Simple Way to Prevent Neural Networks from Overfitting}
\subsection{AlphaDropout}
\pythoninline{keras.layers.AlphaDropout(rate, noise_shape=None, seed=None)}
应用Alpha Dropout到输入，Aalpha Dropout是一个保持输入均值和方差为原始值的Dropout，为了确保在dropout后self-normalizing属性。Alpha Dropout对随机设置激活为负饱和值的大规模指数线性单元拟合很好
\begin{itemize}
\item rate:浮点数，drop的概率。乘性噪声将有标准差sqrt(rate/(1-rate))
\item seed:一个Python整数用作随机种子
\end{itemize}
输入形状任意，用关键字input\_shape(整数元祖，当用这个层在模型的第一层时不包含samplesaxis)

输出形状：和输入形状相同。

参考：\href{https://arxiv.org/abs/1706.02515}{Self-Normalizing Neural Netwroks}
\section{包装器Wrapper}

TimeDistributed包装器
\begin{python}
\subsection{keras.layers.TimeDistributed(layer)}
\end{python}
该包装器可以把一个层应用到输入的每一个时间步上

参数
\begin{itemize}
\item layer：Keras层对象
\end{itemize}
输入至少为3D张量，下标为1的维度将被认为是时间维

例如，考虑一个含有32个样本的batch，每个样本都是10个维向量组成的序列，每个向量长为16，则其输入维度为(32,10,16)，其不包含batch大小的input\_shape为(10,16)

我们可以使用包装器TimeDistributed包装Dense，以产生针对各个时间步信号的独立全连接：
\begin{python}
# as the first layer in a model
model = Sequential()
model.add(TimeDistributed(Dense(8), input_shape=(10, 16)))
# now model.output_shape == (None, 10, 8)

# subsequent layers: no need for input_shape
model.add(TimeDistributed(Dense(32)))
# now model.output_shape == (None, 10, 32)
\end{python}
程序的输出数据shape为(32,10,8)

使用TimeDistributed包装Dense严格等价于layers.TimeDistribuedDense。不同的是包装器TimeDistribued还可以对别的层进行包装，如这里对Conv2D包装：
\begin{python}
model = Sequential()
model.add(TimeDistributed(Conv2D(64, 3, 3), input_shape=(10, 3, 299, 299)))
\end{python}
\subsection{Bidirectional包装器}
\begin{python}
keras.layers.Bidirectional(layer, merge_mode='concat', weights=None)
\end{python}
\subsection{双向RNN包装器}

参数
\begin{itemize}
\item layer：Recurrent对象
\item merge\_mode：前向和后向RNN输出的结合方式，为sum,mul,concat,ave和None之一，若设为None，则返回值不结合，而是以列表的形式返回
\end{itemize}
例子
\begin{python}
model = Sequential()
model.add(Bidirectional(LSTM(10, return_sequences=True), input_shape=(5, 10)))
model.add(Bidirectional(LSTM(10)))
model.add(Dense(5))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
\end{python}
\section{编写自己的层}

对于简单的定制操作，我们或许可以通过使用layers.core.Lambda层来完成。但对于任何具有可训练权重的定制层，你应该自己来实现。

这里是一个Keras2的层应该具有的框架结构(如果你的版本更旧请升级)，要定制自己的层，你需要实现下面三个方法
\begin{itemize}
\item build(input\_shape)：在这里将定义你的权重，这个方法必须设置self.built=True,可以通过调用supper([Layer],self).build()做到
\item call(x)：这是定义层功能的方法，除非你希望你写的层支持masking，否则你只需要关心call的第一个参数：输入张量
\item compute\_output\_shape(input\_shape)：如果你的层修改了输入数据的shape，你应该在这里指定shape变化的方法，这个函数使得Keras可以做自动shape推断
\end{itemize}
\begin{python}
from keras import backend as K
from keras.engine.topology import Layer
import numpy as np

class MyLayer(Layer):

    def __init__(self, output_dim, **kwargs):
        self.output_dim = output_dim
        super(MyLayer, self).__init__(**kwargs)

    def build(self, input_shape):
        # Create a trainable weight variable for this layer.
        self.kernel = self.add_weight(shape=(input_shape[1], self.output_dim),
                                      initializer='uniform',
                                      trainable=True)
        super(MyLayer, self).build(input_shape)  # Be sure to call this somewhere!

    def call(self, x):
        return K.dot(x, self.kernel)

    def compute_output_shape(self, input_shape):
        return (input_shape[0], self.output_dim)
\end{python}
现存的Keras层代码可以为你的实现提供良好参考，阅读源代码吧！
\chapter{数据预处理}\label{ch:preprocessing}
\section{填充序列pad\_sequences}\label{sec:pre1.1}
\begin{python}
keras.preprocessing.sequence.pad_sequences(sequences, maxlen=None, dtype='int32',
    padding='pre', truncating='pre', value=0.)
\end{python}
将长为nb\_samples的序列（标量序列）转化为形如(nb\_samples,nb\_timesteps)2D numpy array。如果提供了参数maxlen，nb\_timesteps=maxlen，否则其值为最长序列的长度。其它短于该长度的序列都会在后部填充0以达到该长度。长于nb\_timesteps的序列将会被截断，以使其匹配目标长度。padding和截断发生的位置分别取决于padding和truncating.

参数
\begin{itemize}
\item sequences：浮点数或整数构成的两层嵌套列表
\item maxlen：None或整数，为序列的最大长度。大于此长度的序列将被截短，小于此长度的序列将在后部填0.
\item dtype：返回的numpy array的数据类型
\item padding：‘pre’或‘post’，确定当需要补0时，在序列的起始还是结尾补
\item truncating：‘pre’或‘post’，确定当需要截断序列时，从起始还是结尾截断
\item value：浮点数，此值将在填充时代替默认的填充值0
\item \end{itemize}
返回值

返回形如(nb\_samples,nb\_timesteps)的2D张量

\section{跳字skipgrams}\label{sec:pre1.2}
\begin{python}
keras.preprocessing.sequence.skipgrams(sequence, vocabulary_size,
    window_size=4, negative_samples=1., shuffle=True,
    categorical=False, sampling_table=None)
\end{python}
skipgrams将一个词向量下标的序列转化为下面的一对tuple：
\begin{itemize}
\item 对于正样本，转化为（word，word in the same window）
\item 对于负样本，转化为（word，random word from the vocabulary）
\end{itemize}
\begin{remark}
根据维基百科，n-gram代表在给定序列中产生连续的n项，当序列为句子时，每项就是单词，此时n-gram也称为shingles。而skip-gram的推广，skip-gram产生的n项子序列中，各个项在原序列中不连续，而是跳了k个字。例如，对于句子：
“the rain in Spain falls mainly on the plain”
其 2-grams为子序列集合：
the rain，rain in，in Spain，Spain falls，falls mainly，mainly on，on the，the plain
其 1-skip-2-grams为子序列集合：
the in, rain Spain, in falls, Spain mainly, falls on, mainly the, on plain.
\end{remark}
更多详情请参考\href{http://arxiv.org/pdf/1301.3781v3.pdf}{Efficient Estimation of Word Representations in Vector Space}

参数
\begin{itemize}
\item sequence：下标的列表，如果使用sampling\_tabel，则某个词的下标应该为它在数据库中的顺序。（从1开始）
\item vocabulary\_size：整数，字典大小
\item window\_size：整数，正样本对之间的最大距离
\item negative\_samples：大于0的浮点数，等于0代表没有负样本，等于1代表负样本与正样本数目相同，以此类推（即负样本的数目是正样本的negative\_samples倍）
\item shuffle：布尔值，确定是否随机打乱样本
\item categorical：布尔值，确定是否要使得返回的标签具有确定类别
\item sampling\_table：形如(vocabulary\_size,)的numpy array，其中sampling\_table[i]代表没有负样本或随机负样本。等于1为与正样本的数目相同 采样到该下标为i的单词的概率（假定该单词是数据库中第i常见的单词）
\end{itemize}
输出

函数的输出是一个(couples,labels)的元组，其中：
\begin{itemize}
\item couples是一个长为2的整数列表：[word\_index,other\_word\_index]
\item labels是一个仅由0和1构成的列表，1代表other\_word\_index在word\_index的窗口，0代表other\_word\_index是词典里的随机单词。
\item 如果设置categorical为True，则标签将以one-hot的方式给出，即1变为[0,1]，0变为[1,0]
\item 获取采样表make\_sampling\_table
\end{itemize}
\begin{python}
keras.preprocessing.sequence.make_sampling_table(size, sampling_factor=1e-5)
\end{python}
该函数用以产生skipgrams中所需要的参数sampling\_table。这是一个长为size的向量，sampling\_table[i]代表采样到数据集中第i常见的词的概率（为平衡期起见，对于越经常出现的词，要以越低的概率采到它）

参数
\begin{itemize}
\item size：词典的大小
\item sampling\_factor：此值越低，则代表采样时更缓慢的概率衰减（即常用的词会被以更低的概率被采到），如果设置为1，则代表不进行下采样，即所有样本被采样到的概率都是1。
\end{itemize}
\section{文本预处理}\label{sec:pre1.3}

句子分割text\_to\_word\_sequence
\begin{python}
keras.preprocessing.text.text_to_word_sequence(text,
                                               filters='!"#\$%&()*+,-./:;<=>?@[\]^_`{|}~\t\n',
                                               lower=True,
                                               split=" ")
\end{python}
本函数将一个句子拆分成单词构成的列表

参数
\begin{itemize}
    \item text：字符串，待处理的文本
    \item filters：需要滤除的字符的列表或连接形成的字符串，例如标点符号。默认值为 `!\"\#\$
\&()*+,-./:;`<=>?@[]\^{}\_\`{}\{|\}\~\textbackslash{}t\textbackslash{}n`，包含标点符号，制表符和换行符等

    \item lower：布尔值，是否将序列设为小写形式
    \item split：字符串，单词的分隔符，如空格
\end{itemize}

返回值

字符串列表

\section{one-hot编码}\label{sec:pre1.4}
\begin{python}
keras.preprocessing.text.one_hot(text,
                                 n,
                                 filters='!"#$%&()*+,-./:;<=>?@[\]^_`{|}~\t\n',
                                 lower=True,
                                 split=" ")
\end{python}
本函数将一段文本编码为one-hot形式的码，即仅记录词在词典中的下标。
\begin{remark}
从定义上，当字典长为n时，每个单词应形成一个长为n的向量，其中仅有单词本身在字典中下标的位置为1，其余均为0，这称为one-hot。
\end{remark}
为了方便起见，函数在这里仅把“1”的位置，即字典中词的下标记录下来。

\textbf{参数}:
\begin{itemize}
\item n：整数，字典长度
\end{itemize}

\textbf{返回值}

整数列表，每个整数是[1,n]之间的值，代表一个单词（不保证唯一性，即如果词典长度不够，不同的单词可能会被编为同一个码）。

\section{特征哈希hashing\_trick}\label{sec:pre1.5}
\begin{python}
keras.preprocessing.text.hashing_trick(text,
                                       n,
                                       hash_function=None,
                                       filters='!"#$%&()*+,-./:;<=>?@[\]^_`{|}~\t\n',
                                       lower=True,
                                       split=' ')
\end{python}
将文本转换为固定大小的哈希空间中的索引序列

参数
\begin{itemize}
\item n: 哈希空间的维度
\item hash\_function: 默认为 python hash 函数, 可以是 'md5' 或任何接受输入字符串, 并返回 int 的函数. 注意 hash 不是一个稳定的哈希函数, 因此在不同执行环境下会产生不同的结果, 作为对比, 'md5' 是一个稳定的哈希函数.
\end{itemize}

返回值

整数列表

\section{分词器Tokenizer}\label{sec:pre1.6}
\begin{python}
keras.preprocessing.text.Tokenizer(num_words=None,
filters='!"#$%&()*+,-./:;<=>?@[\]^_`{|}~\t\n',
lower=true,
split=" ",
char_level=false)
\end{python}
tokenizer是一个用于向量化文本，或将文本转换为序列（即单词在字典中的下标构成的列表，从1算起）的类。

构造参数
\begin{itemize}
\item 与text\_to\_word\_sequence同名参数含义相同
\item num\_words：None或整数，处理的最大单词数量。若被设置为整数，则分词器将被限制为待处理数据集中最常见的num\_words个单词
\item char\_level: 如果为 True, 每个字符将被视为一个标记
\end{itemize}

类方法
\begin{itemize}
\item fit\_on\_texts(texts)
\begin{itemize}
\item texts：要用以训练的文本列表
\end{itemize}
\item texts\_to\_sequences(texts)
\begin{itemize}
\item texts：待转为序列的文本列表
\item 返回值：序列的列表，列表中每个序列对应于一段输入文本
\end{itemize}

\item{texts\_to\_sequences\_generator(texts)}
\begin{itemize}
\item 本函数是texts\_to\_sequences的生成器函数版
\item texts：待转为序列的文本列表
\item 返回值：每次调用返回对应于一段输入文本的序列
\end{itemize}

\item texts\_to\_matrix(texts, mode)：
\begin{itemize}
\item texts：待向量化的文本列表
\item mode：‘binary’，‘count’，‘tfidf’，‘freq’之一，默认为‘binary’
\item 返回值：形如(len(texts), nb\_words)的numpy array
\end{itemize}

\item fit\_on\_sequences(sequences):
\begin{itemize}
\item sequences：要用以训练的序列列表
\end{itemize}
\item sequences\_to\_matrix(sequences):
\begin{itemize}
\item sequences：待向量化的序列列表
\item mode：‘binary’，‘count’，‘tfidf’，‘freq’之一，默认为‘binary’
\item 返回值：形如(len(sequences), nb\_words)的numpy array
\end{itemize}
\end{itemize}

属性
\begin{itemize}
\item word\_counts:字典，将单词（字符串）映射为它们在训练期间出现的次数。仅在调用fit\_on\_texts之后设置。
\item word\_docs: 字典，将单词（字符串）映射为它们在训练期间所出现的文档或文本的数量。仅在调用fit\_on\_texts之后设置。
\item word\_index: 字典，将单词（字符串）映射为它们的排名或者索引。仅在调用fit\_on\_texts之后设置。
\item document\_count: 整数。分词器被训练的文档（文本或者序列）数量。仅在调用fit\_on\_texts或fit\_on\_sequences之后设置。
\end{itemize}
\section{图片预处理}\label{sec:pre1.7}

图片生成器imageDataGenerator
\begin{python}
keras.preprocessing.image.ImageDataGenerator(featurewise_center=False,
    samplewise_center=False,
    featurewise_std_normalization=False,
    samplewise_std_normalization=False,
    zca_whitening=False,
    zca_epsilon=1e-6,
    rotation_range=0.,
    width_shift_range=0.,
    height_shift_range=0.,
    shear_range=0.,
    zoom_range=0.,
    channel_shift_range=0.,
    fill_mode='nearest',
    cval=0.,
    horizontal_flip=False,
    vertical_flip=False,
    rescale=none,
    preprocessing_function=None,
    data_format=K.image_data_format())
\end{python}
用以生成一个batch的图像数据，支持实时数据提升。训练时该函数会无限生成数据，直到达到规定的epoch次数为止。

参数
\begin{itemize}
\item featurewise\_center：布尔值，使输入数据集去中心化（均值为0）, 按feature执行
\item samplewise\_center：布尔值，使输入数据的每个样本均值为0
\item featurewise\_std\_normalization：布尔值，将输入除以数据集的标准差以完成标准化, 按feature执行
\item samplewise\_std\_normalization：布尔值，将输入的每个样本除以其自身的标准差
\item zca\_whitening：布尔值，对输入数据施加ZCA白化
\item zca\_epsilon: ZCA使用的eposilon，默认1e-6
\item rotation\_range：整数，数据提升时图片随机转动的角度
\item width\_shift\_range：浮点数，图片宽度的某个比例，数据提升时图片水平偏移的幅度
\item height\_shift\_range：浮点数，图片高度的某个比例，数据提升时图片竖直偏移的幅度
\item shear\_range：浮点数，剪切强度（逆时针方向的剪切变换角度）
\item zoom\_range：浮点数或形如[lower,upper]的列表，随机缩放的幅度，若为浮点数，则相当于[lower,upper] = [1 - zoom\_range, 1+zoom\_range]
\item channel\_shift\_range：浮点数，随机通道偏移的幅度
\item fill\_mode：；‘constant’，‘nearest’，‘reflect’或‘wrap’之一，当进行变换时超出边界的点将根据本参数给定的方法进行处理
\item cval：浮点数或整数，当fill\_mode=constant时，指定要向超出边界的点填充的值
\item horizontal\_flip：布尔值，进行随机水平翻转
\item vertical\_flip：布尔值，进行随机竖直翻转
\item rescale: 重放缩因子,默认为None. 如果为None或0则不进行放缩,否则会将该数值乘到数据上(在应用其它变换之前)
\item preprocessing\_function: 将被应用于每个输入的函数。该函数将在任何其它修改之前运行。该函数接受一个参数，为一张图片（秩为3的numpy array），并且输出一个具有相同shape的numpy array
\item data\_format：字符串，“channel\_first”或“channel\_last”之一，代表图像的通道维的位置。该参数是Keras 1.x中的image\_dim\_ordering，“channel\_last”对应原本的“tf”，“channel\_first”对应原本的“th”。以128x128的RGB图像为例，“channel\_first”应将数据组织为（3,128,128），而“channel\_last”应将数据组织为（128,128,3）。该参数的默认值是~/.keras/keras.json中设置的值，若从未设置过，则为“channel\_last”
\end{itemize}

方法
\begin{itemize}
\item fit(x, augment=False, rounds=1)：计算依赖于数据的变换所需要的统计信息(均值方差等),只有使用featurewise\_center，featurewise\_std\_normalization或zca\_whitening时需要此函数。
\begin{itemize}
\item x：numpy array，样本数据，秩应为4.在黑白图像的情况下channel轴的值为1，在彩色图像情况下值为3
\item augment：布尔值，确定是否使用随即提升过的数据
\item round：若设augment=True，确定要在数据上进行多少轮数据提升，默认值为1
\item seed: 整数,随机数种子
\end{itemize}

\item flow(self, X, y, batch\_size=32, shuffle=True, seed=None, save\_to\_dir=None, save\_prefix='', save\_format='png')：接收numpy数组和标签为参数,生成经过数据提升或标准化后的batch数据,并在一个无限循环中不断的返回batch数据
\begin{itemize}
\item x：样本数据，秩应为4.在黑白图像的情况下channel轴的值为1，在彩色图像情况下值为3
\item y：标签
\item batch\_size：整数，默认32
\item shuffle：布尔值，是否随机打乱数据，默认为True
\item save\_to\_dir：None或字符串，该参数能让你将提升后的图片保存起来，用以可视化
\item save\_prefix：字符串，保存提升后图片时使用的前缀, 仅当设置了save\_to\_dir时生效
\item save\_format："png"或"jpeg"之一，指定保存图片的数据格式,默认"jpeg"
\item yields:形如(x,y)的tuple,x是代表图像数据的numpy数组.y是代表标签的numpy数组.该迭代器无限循环.
\item seed: 整数,随机数种子
\end{itemize}
\item flow\_from\_directory(directory): 以文件夹路径为参数,生成经过数据提升/归一化后的数据,在一个无限循环中无限产生batch数据
\begin{itemize}
\item directory: 目标文件夹路径,对于每一个类,该文件夹都要包含一个子文件夹.子文件夹中任何JPG、PNG和BNP的图片都会被生成器使用.详情请查看此脚本
\item target\_size: 整数tuple,默认为(256, 256). 图像将被resize成该尺寸
\item color\_mode: 颜色模式,为"grayscale","rgb"之一,默认为"rgb".代表这些图片是否会被转换为单通道或三通道的图片.
\item classes: 可选参数,为子文件夹的列表,如['dogs','cats']默认为None. 若未提供,则该类别列表将从directory下的子文件夹名称/结构自动推断。每一个子文件夹都会被认为是一个新的类。(类别的顺序将按照字母表顺序映射到标签值)。通过属性class\_indices可获得文件夹名与类的序号的对应字典。
\item class\_mode: "categorical", "binary", "sparse"或None之一. 默认为"categorical. 该参数决定了返回的标签数组的形式, "categorical"会返回2D的one-hot编码标签,"binary"返回1D的二值标签."sparse"返回1D的整数标签,如果为None则不返回任何标签, 生成器将仅仅生成batch数据, 这种情况在使用model.predict\_generator()和model.evaluate\_generator()等函数时会用到.
\item batch\_size: batch数据的大小,默认32
\item shuffle: 是否打乱数据,默认为True
\item seed: 可选参数,打乱数据和进行变换时的随机数种子
\item save\_to\_dir: None或字符串，该参数能让你将提升后的图片保存起来，用以可视化
\item save\_prefix：字符串，保存提升后图片时使用的前缀, 仅当设置了save\_to\_dir时生效
\item save\_format："png"或"jpeg"之一，指定保存图片的数据格式,默认"jpeg"
\item flollow\_links: 是否访问子文件夹中的软链接
\end{itemize}
\end{itemize}
例子

使用.flow()的例子
\begin{python}
(x_train, y_train), (x_test, y_test) = cifar10.load_data()
y_train = np_utils.to_categorical(y_train, num_classes)
y_test = np_utils.to_categorical(y_test, num_classes)

datagen = imageDataGenerator(
    featurewise_center=True,
    featurewise_std_normalization=True,
    rotation_range=20,
    width_shift_range=0.2,
    height_shift_range=0.2,
    horizontal_flip=True)

# compute quantities required for featurewise normalization
# (std, mean, and principal components if ZCA whitening is applied)
datagen.fit(x_train)

# fits the model on batches with real-time data augmentation:
model.fit_generator(datagen.flow(x_train, y_train, batch_size=32),
                    steps_per_epoch=len(x_train), epochs=epochs)

# here's a more "manual" example
for e in range(epochs):
    print 'epoch', e
    batches = 0
    for x_batch, y_batch in datagen.flow(x_train, y_train, batch_size=32):
        loss = model.train(x_batch, y_batch)
        batches += 1
        if batches >= len(x_train) / 32:
            # we need to break the loop by hand because
            # the generator loops indefinitely
            break
\end{python}
使用.flow\_from\_directory(directory)的例子
\begin{python}
train_datagen = ImageDataGenerator(
        rescale=1./255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True)

test_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(
        'data/train',
        target_size=(150, 150),
        batch_size=32,
        class_mode='binary')

validation_generator = test_datagen.flow_from_directory(
        'data/validation',
        target_size=(150, 150),
        batch_size=32,
        class_mode='binary')

model.fit_generator(
        train_generator,
        steps_per_epoch=2000,
        epochs=50,
        validation_data=validation_generator,
        validation_steps=800)
\end{python}
同时变换图像和mask
\begin{python}
# we create two instances with the same arguments
data_gen_args = dict(featurewise_center=True,
                     featurewise_std_normalization=True,
                     rotation_range=90.,
                     width_shift_range=0.1,
                     height_shift_range=0.1,
                     zoom_range=0.2)
image_datagen = ImageDataGenerator(**data_gen_args)
mask_datagen = ImageDataGenerator(**data_gen_args)

# provide the same seed and keyword arguments to the fit and flow methods
seed = 1
image_datagen.fit(images, augment=True, seed=seed)
mask_datagen.fit(masks, augment=True, seed=seed)

image_generator = image_datagen.flow_from_directory(
    'data/images',
    class_mode=None,
    seed=seed)

mask_generator = mask_datagen.flow_from_directory(
    'data/masks',
    class_mode=None,
    seed=seed)

# combine generators into one which yields image and masks
train_generator = zip(image_generator, mask_generator)

model.fit_generator(
    train_generator,
    steps_per_epoch=2000,
    epochs=50)
\end{python}
\chapter{目标函数objectives}\label{ch:obj}

目标函数，或称损失函数，是编译一个模型必须的两个参数之一：
\begin{python}
model.compile(loss='mean_squared_error', optimizer='sgd')
\end{python}
可以通过传递预定义目标函数名字指定目标函数，也可以传递一个Theano/TensroFlow的符号函数作为目标函数，该函数对每个数据点应该只返回一个标量值，并以下列两个参数为参数：
\begin{itemize}
\item y\_true：真实的数据标签，Theano/TensorFlow张量
\item y\_pred：预测值，与y\_true相同shape的Theano/TensorFlow张量
\end{itemize}
\begin{python}
from keras import losses
model.compile(loss=losses.mean_squared_error, optimizer='sgd')
\end{python}
真实的优化目标函数是在各个数据点得到的损失函数值之和的均值

请参考目标实现代码获取更多信息

可用的目标函数(下面公式中$Y_p$表示预测值，$Y_t$表示真实值)
\begin{itemize}
\item mean\_squared\_error或mse。表达式如下：
	\begin{equation}
		mse = \frac{1}{n}\sum_{i=1}^n(Y_{ip}-Y_{it})^2
	\end{equation}
	空间上两个点的距离。
\item mean\_absolute\_error或mae
	\begin{equation}
		mae = \frac{1}{n}\sum_{i=1}^n|Y_p-Y_t|=\frac{1}{n}\sum_{i=1}^n|e_i|(e_i=|Y_p-Y_t|)
	\end{equation}
\item mean\_absolute\_percentage\_error(平均绝对百分比误差)或mape
	\begin{equation}
		m = \frac{1}{n}\sum_{i=1}^n|\frac{Y_{pi}-Y_{ti}}{Y_{ti}}|
	\end{equation}
\item mean\_squared\_logarithmic\_error(均方对数误差)或msle
	\begin{equation}
		\epsilon = \frac{1}{n}\sum_{i=1}^n(log(p_i+1)-log(a_i+1))^2
	\end{equation}
		n表示数据集元素个数，$p_{ti}$表示第i个真实值，$y_{pi}$表示第i个预测值。
\item squared\_hinge
	\begin{equation}
		max(0,1-y_t*y_p)^2.mean(axis=-1)
	\end{equation}
	取1减去预测值与实际值的乘积的结构和0比相对大的值的累加和的均值
\item hinge
　公式为为$max(0,1-y_true*y_pred).mean(axis=-1)$，取1减去预测值与实际值的乘积的结果与0比相对大的值的累加均值。　　Hinge Loss 最常用在 SVM 中的最大化间隔分类中，对可能的输出 $t \pm 1$ 和分类器分数 y，预测值 y 的 hinge loss 定义如下：
　　\[l(y) = max(0,1-t*y)\]
看到 y 应当是分类器决策函数的“原始”输出，而不是最终的类标。例如，在线性的 SVM 中$y = w*x+b$可以看出当 t 和 y 有相同的符号时（意味着 y 预测出正确的分类）$|y|>=1$　此时的 hinge loss $L(y) = 0$　但是如果它们的符号相反　　L(y)则会根据 y 线性增加 one-sided error。

\item categorical\_hinge
\item binary\_crossentropy（亦称作对数损失，logloss）
\begin{equation}
l(y,p(y|x)) = -log P(Y|X)
\end{equation}
该函数主要用来做极大似然估计的，这样做会方便计算。因为极大似然估计用来求导会非常的麻烦，一般是求对数然后求导再求极值点。损失函数一般是每条数据的损失之和，恰好取了对数，就可以把每个损失相加起来。负号的意思是极大似然估计对应最小损失。
\item logcosh
\item categorical\_crossentropy：亦称作多类的对数损失，注意使用该目标函数时，需要将标签转化为形如(nb\_samples, nb\_classes)的二值序列
\item sparse\_categorical\_crossentrop：如上，但接受稀疏标签。注意，使用该函数时仍然需要你的标签与输出值的维度相同，你可能需要在标签数据上增加一个维度：np.expand\_dims(y,-1)
\item kullback\_leibler\_divergence:从预测值概率分布Q到真值概率分布P的信息增益,用以度量两个分布的差异.
\item poisson：即(predictions - targets * log(predictions))的均值
\item cosine\_proximity：即预测值与真实标签的余弦距离平均值的相反数
\begin{equation}
\begin{split}
cos\theta = \frac{\sum_{i=1}^n(A_i\times B_i)}{\sqrt{\sum_{i}^nA^2_i\times\sqrt{\sum_{i=1}^nB_i^2}}}\\
\epsilon = -\frac{1}{m}\sum_{i=1}^mcos_i\theta
\end{split}
\end{equation}
\end{itemize}
注意: 当使用"categorical\_crossentropy"作为目标函数时,标签应该为多类模式,即one-hot编码的向量,而不是单个数值. 可以使用工具中的to\_categorical函数完成该转换.示例如下:
\begin{python}
from keras.utils.np_utils import to_categorical
categorical_labels = to_categorical(int_labels, num_classes=None)
\end{python}
\chapter{优化器optimizers}\label{ch:优化器}

优化器是编译keras模型必要的两个参数之一
\begin{python}
from keras import optimizers
model = sequential()
model.add(dense(64, kernel_initializer='uniform', input_shape=(10,)))
model.add(activation('tanh'))
model.add(activation('softmax'))
sgd = optimizers.SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='mean_squared_error', optimizer=sgd)
\end{python}
可以在调用model.compile()之前初始化一个优化器对象，然后传入该函数（如上所示），也可以在调用model.compile()时传递一个预定义优化器名。在后者情形下，优化器的参数将使用默认值。
\begin{python}
# pass optimizer by name: default parameters will be used
model.compile(loss='mean_squared_error', optimizer='sgd')
\end{python}
\section{所有优化器都可用的参数}\label{sec:obj1}

参数clipnorm和clipvalue是所有优化器都可以使用的参数,用于对梯度进行裁剪.示例如下:
\begin{python}
from keras import optimizers

# all parameter gradients will be clipped to
# a maximum norm of 1.
sgd = optimizers.SGD(lr=0.01, clipnorm=1.)
from keras import optimizers

# all parameter gradients will be clipped to
# a maximum value of 0.5 and
# a minimum value of -0.5.
sgd = optimizers.SGD(lr=0.01, clipvalue=0.5)
\end{python}
\subsection{sgD}\label{sec:obj2}

keras.optimizers.SGD(lr=0.01, momentum=0.0, decay=0.0, nesterov=False)
随机梯度下降法，支持动量参数，支持学习衰减率，支持Nesterov动量

参数
\begin{itemize}
\item lr：大或等于0的浮点数，学习率
\item momentum：大或等于0的浮点数，动量参数
\item decay：大或等于0的浮点数，每次更新后的学习率衰减值
\item nesterov：布尔值，确定是否使用Nesterov动量
\end{itemize}
\subsection{rmSprop}\label{sec:obj3}
\begin{python}
keras.optimizers.RMSprop(lr=0.001, rho=0.9, epsilon=1e-06)
\end{python}
除学习率可调整外，建议保持优化器的其他默认参数不变

该优化器通常是面对递归神经网络时的一个良好选择

参数
\begin{itemize}
\item lr：大或等于0的浮点数，学习率
\item rho：大或等于0的浮点数
\item epsilon：大或等于0的小浮点数，防止除0错误
\end{itemize}

\subsection{adagrad}\label{sec:obj4}
\begin{python}
keras.optimizers.Adagrad(lr=0.01, epsilon=1e-06)
\end{python}
建议保持优化器的默认参数不变

adagrad
\begin{itemize}
\item lr：大或等于0的浮点数，学习率
\item epsilon：大或等于0的小浮点数，防止除0错误
\end{itemize}

\subsection{adadelta}\label{sec:obj5}
\begin{itemize}
\item keras.optimizers.Adadelta(lr=1.0, rho=0.95, epsilon=1e-06)
\end{itemize}
建议保持优化器的默认参数不变

参数
\begin{itemize}
\item lr：大或等于0的浮点数，学习率
\item rho：大或等于0的浮点数
\item epsilon：大或等于0的小浮点数，防止除0错误
\end{itemize}

参考文献

\href{http://arxiv.org/abs/1212.5701}{Adadelta - an adaptive learning rate method}
\subsection{adam}\label{sec:obj6}
\begin{python}
keras.optimizers.Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
\end{python}
该优化器的默认值来源于参考文献

参数
\begin{itemize}
\item lr：大或等于0的浮点数，学习率
\item beta\_1/beta\_2：浮点数， 0<beta<1，通常很接近1
\item epsilon：大或等于0的小浮点数，防止除0错误
\end{itemize}

参考文献

\href{http://arxiv.org/abs/1412.6980v8}{Adam - A Method for Stochastic Optimization}
\subsection{adamax}\label{sec:obj7}
\begin{python}
keras.optimizers.Adamax(lr=0.002, beta_1=0.9, beta_2=0.999, epsilon=1e-08)
\end{python}
adamax优化器来自于Adam的论文的subsection7，该方法是基于无穷范数的Adam方法的变体。

默认参数由论文提供

参数
\begin{itemize}
\item lr：大或等于0的浮点数，学习率
\item beta\_1/beta\_2：浮点数， 0<beta<1，通常很接近1
\item epsilon：大或等于0的小浮点数，防止除0错误
\end{itemize}

参考文献

\href{http://arxiv.org/abs/1412.6980v8}{Adam - A Method for Stochastic Optimization}
\subsection{nadam}\label{sec:obj8}
\begin{python}
keras.optimizers.Nadam(lr=0.002, beta_1=0.9, beta_2=0.999, epsilon=1e-08, schedule_decay=0.004)
\end{python}
nesterov adam optimizer: Adam本质上像是带有动量项的RMSprop，Nadam就是带有Nesterov 动量的Adam RMSprop

默认参数来自于论文，推荐不要对默认参数进行更改。

参数
\begin{itemize}
\item lr：大或等于0的浮点数，学习率
\item beta\_1/beta\_2：浮点数， 0<beta<1，通常很接近1
\item epsilon：大或等于0的小浮点数，防止除0错误
\end{itemize}

参考文献
\begin{itemize}
\item \href{http://cs229.stanford.edu/proj2015/054_report.pdf}{Nadam report}
\item \href{http://www.cs.toronto.edu/~fritz/absps/momentum.pdf}{On the importance of initialization and momentum in deep learning}

\end{itemize}
\subsection{tfOptimizer}\label{sec:obj9}
\begin{python}
keras.optimizers.TFOptimizer(optimizer)
\end{python}
tf优化器的包装器
\chapter{激活函数Activations}\label{ch:activation}

激活函数可以通过设置单独的激活层实现，也可以在构造层对象时通过传递activation参数实现。
\begin{python}
from keras.layers import Activation, Dense

model.add(dense(64))
model.add(activation('tanh'))
\end{python}
等价于
\begin{python}
model.add(dense(64, activation='tanh'))
\end{python}
也可以通过传递一个逐元素运算的Theano/TensorFlow/CNTK函数来作为激活函数：
\begin{python}
from keras import backend as K

def tanh(x):
    return k.tanh(x)

model.add(dense(64, activation=tanh))
model.add(activation(tanh)
\end{python}
预定义激活函数
\begin{itemize}
\item softmax：对输入数据的最后一维进行softmax，输入数据应形如(nb\_samples, \item nb\_timesteps, nb\_dims)或(nb\_samples,nb\_dims)
\item elu
\item selu: 可伸缩的指数线性单元（Scaled Exponential Linear Unit），参考Self-Normalizing Neural Networks
\item softplus
\item softsign
\item relu
\item tanh
\item sigmoid
\item hard\_sigmoid
\item linear
\end{itemize}
\section{高级激活函数}\label{sec:obj10}

对于简单的theano/TensorFlow/CNTK不能表达的复杂激活函数，如含有可学习参数的激活函数，可通过高级激活函数实现，如PReLU，LeakyReLU等
\chapter{性能评估}

\section{使用方法}\label{sec:obj11}

性能评估模块提供了一系列用于模型性能评估的函数,这些函数在模型编译时由metrics关键字设置

性能评估函数类似与目标函数, 只不过该性能的评估结果讲不会用于训练.

可以通过字符串来使用域定义的性能评估函数
\begin{python}
model.compile(loss='mean_squared_error',
              optimizer='sgd',
              metrics=['mae', 'acc'])
\end{python}
也可以自定义一个Theano/TensorFlow函数并使用之
\begin{python}
from keras import metrics

model.compile(loss='mean_squared_error',
              optimizer='sgd',
              metrics=[metrics.mae, metrics.categorical_accuracy])
\end{python}
参数
\begin{itemize}
\item y\_true:真实标签,theano/tensorflow张量
\item y\_pred:预测值, 与y\_true形式相同的theano/tensorflow张量
\end{itemize}

返回值

单个用以代表输出各个数据点上均值的值

\section{可用预定义张量}\label{sec:obj12}

除fbeta\_score额外拥有默认参数beta=1外,其他各个性能指标的参数均为y\_true和y\_pred
\begin{itemize}
\item binary\_accuracy: 对二分类问题,计算在所有预测值上的平均正确率
\item categorical\_accuracy:对多分类问题,计算再所有预测值上的平均正确率
\item sparse\_categorical\_accuracy:与categorical\_accuracy相同,在对稀疏的目标值预测时有用
\item top\_k\_categorical\_accracy: 计算top-k正确率,当预测值的前k个值中存在目标类别即认为预测正确
\item sparse\_top\_k\_categorical\_accuracy：与top\_k\_categorical\_accracy作用相同，
\end{itemize}
但适用于稀疏情况
\section{定制评估函数}\label{sec:obj13}

定制的评估函数可以在模型编译时传入,该函数应该以(y\_true, y\_pred)为参数,并返回单个张量,或从metric\_name映射到metric\_value的字典,下面是一个示例:
\begin{python}
(y_true, y_pred) as arguments and return a single tensor value.

import keras.backend as K

def mean_pred(y_true, y_pred):
    return k.mean(y_pred)

model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy', mean_pred])

\end{python}
\chapter{初始化方法}\label{ch:初始化方法}

初始化方法定义了对Keras层设置初始化权重的方法，不同的层可能使用不同的关键字来传递初始化方法，一般来说指定初始化方法的关键字是kernel\_initializer 和 bias\_initializer，例如：
\begin{python}
model.add(dense(64,
                kernel_initializer='random_uniform',
                bias_initializer='zeros'))
\end{python}
一个初始化器可以由字符串指定（必须是下面的预定义初始化器之一），或一个callable的函数，例如
\begin{python}
from keras import initializers
model.add(dense(64, kernel_initializer=initializers.random_normal(stddev=0.01)))
# also works; will use the default parameters.
model.add(dense(64, kernel_initializer='random_normal'))
\end{python}
\subsection{initializer}\label{sec:obj14}

initializer是所有初始化方法的父类，不能直接使用，如果想要定义自己的初始化方法，请继承此类。
预定义初始化方法：
\begin{itemize}
    \item Zeros：全零初始化
    \begin{python}
        keras.initializers.Zeros()
    \end{python}

    \item Ones：全1初始化
    \begin{python}
        keras.initializers.Ones()
    \end{python}
    \item Constant：初始化为固定值value
    \begin{python}
        keras.initializers.Constant(value=0)
    \end{python}

    \item RandomNormal：正态分布初始化
    \begin{python}
        keras.initializers.RandomNormal(mean=0.0, stddev=0.05, seed=None))
    \end{python}
    \begin{itemize}
        \item mean：均值
        \item stddev：标准差
        \item seed：随机数种子
    \end{itemize}

    \item RandomUniform：均匀分布初始化 minval：均匀分布下边界 maxval：均匀分布上边界 * seed：随机数种子
    \begin{python}
        keras.initializers.RandomUniform(minval=-0.05, maxval=0.05, seed=None)
    \end{python}
    \item TruncatedNormal：截尾高斯分布初始化，该初始化方法与RandomNormal类似，但位于均值两个标准差以外的数据将会被丢弃并重新生成，形成截尾分布。该分布是神经网络权重和滤波器的推荐初始化方法。
    \begin{python}
        keras.initializers.TruncatedNormal(mean=0.0, stddev=0.05, seed=None)
    \end{python}
    \begin{itemize}
        \item mean：均值
        \item stddev：标准差
        \item seed：随机数种子
    \end{itemize}

    \item VarianceScaling：该初始化方法能够自适应目标张量的shape。当distribution="normal"时，样本从0均值，标准差为sqrt(scale / n)的截尾正态分布中产生。其中：
    \begin{python}
        keras.initializers.VarianceScaling(scale=1.0, mode='fan_in', distribution='normal', seed=None)
    \end{python}
    \begin{itemize}
        \item[*] 当model = "fan\_in"时，权重张量的输入单元数。
        \item[*] 当mode = "fan\_out"时，权重张量的输出单元数
        \item[*] 当mode = "fan\_avg"时，权重张量的输入输出单元数的均值
    \end{itemize}
    当distribution="uniform"时，权重从[-limit, limit]范围内均匀采样，其中limit = limit = sqrt(3 * scale / n)
    \begin{itemize}
        \item scale: 放缩因子，正浮点数
        \item mode: 字符串，“fan\_in”，“fan\_out”或“fan\_avg”fan\_in", "fan\_out", "fan\_avg".
        \item distribution: 字符串，“normal”或“uniform”.
        \item seed: 随机数种子
    \end{itemize}

    \item Orthogonal：用随机正交矩阵初始化
    \begin{python}
        keras.initializers.Orthogonal(gain=1.0, seed=None)
    \end{python}
    \begin{itemize}
        \item gain: 正交矩阵的乘性系数
        \item seed：随机数种子
    \end{itemize}
参考文献：\href{http://arxiv.org/abs/1312.6120}{Saxe et al.}

    \item Identiy：使用单位矩阵初始化，仅适用于2D方阵
    \begin{python}
        keras.initializers.Identity(gain=1.0)
    \end{python}
    \begin{itemize}
        \item gain：单位矩阵的乘性系数
    \end{itemize}
    \item lecun\_uniform:LeCun均匀分布初始化方法，参数由[-limit, limit]的区间中均匀采样获得，其中limit=sqrt(3 / fan\_in), fin\_in是权重向量的输入单元数（扇入）

    \begin{python}
        lecun_uniform(seed=None)
    \end{python}
    \begin{itemize}
        \item seed：随机数种子
    \end{itemize}

    参考文献：\href{http://yann.lecun.com/exdb/publis/pdf/lecun-98b.pdf}{LeCun 98, Efficient Backprop}\cite{lecun_efficient_1998}

    \item lecun\_normal:LeCun正态分布初始化方法，参数由0均值，标准差为stddev = sqrt(1 / fan\_in)的正态分布产生，其中fan\_in和fan\_out是权重张量的扇入扇出（即输入和输出单元数目）,seed表示随机种子。
    \begin{python}
        lecun_normal(seed=None)
    \end{python}
    参考文献：
    \begin{itemize}
        \item \href{https://arxiv.org/abs/1706.02515}{Self-Normalizing Neural Networks Efficient Backprop}

    \end{itemize}
\item glorot\_normal:Glorot正态分布初始化方法，也称作Xavier正态分布初始化，参数由0均值，标准差为sqrt(2 / (fan\_in + fan\_out))的正态分布产生，其中fan\_in和fan\_out是权重张量的扇入扇出（即输入和输出单元数目),seed表示随机数种子。
    \begin{itemize}
        \item glorot\_normal(seed=None)
    \end{itemize}
参考文献：\href{http://jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf}{Glorot \& Bengio, AISTATS 2010}

    \item glorot\_uniform:Glorot均匀分布初始化方法，又成Xavier均匀初始化，参数从[-limit, limit]的均匀分布产生，其中limit为sqrt(6 / (fan\_in + fan\_out))。fan\_in为权值张量的输入单元数，fan\_out是权重张量的输出单元数。seed表示随机数种子。
    \begin{python}
        glorot_uniform(seed=None)
    \end{python}
    参考文献：\href{http://jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf}{Glorot \& Bengio, AISTATS 2010}

    \item he\_normal:He正态分布初始化方法，参数由0均值，标准差为sqrt(2 / fan\_in) 的正态分布产生，其中fan\_in权重张量的扇入,seed表示随机数种子。
    \begin{python}
        he_normal(seed=None)
    \end{python}

参考文献：\href{http://arxiv.org/abs/1502.01852}{He et al}

    \item he\_uniform
    \begin{python}
        he_normal(seed=None)
    \end{python}
        LeCun均匀分布初始化方法，参数由[-limit, limit]的区间中均匀采样获得，其中limit=sqrt(6 / fan\_in), fin\_in是权重向量的输入单元数（扇入）。seed表示随机数种子。
    \begin{python}
    model.add(Dense(64, input_dim=64,
                kernel_regularizer=regularizers.l2(0.01),
                activity_regularizer=regularizers.l1(0.01)))
    \end{python}
    \end{itemize}
\section{可用正则项}
\begin{itemize}
    \item keras.regularizers.l1(0.)
    \item keras.regularizers.l2(0.)
    \item keras.regularizers.l1\_l2(0.)
\end{itemize}
\section{开发新的正则项}\label{sec:obj22}

任何以权重矩阵作为输入并返回单个数值的函数均可以作为正则项，示例：
\begin{python}
from keras import backend as K

def l1_reg(weight_matrix):
    return 0.01 * K.sum(K.abs(weight_matrix))

model.add(Dense(64, input_dim=64,
                kernel_regularizer=l1_reg)
\end{python}

可参考源代码\href{https://github.com/fchollet/keras/blob/master/keras/regularizers.py}{keras/regularizer.py}

\chapter{回调函数Callbacks}\label{ch:callbacks}

回调函数是一组在训练的特定阶段被调用的函数集，你可以使用回调函数来观察训练过程中网络内部的状态和统计信息。通过传递回调函数列表到模型的.fit()中，即可在给定的训练阶段调用该函数集中的函数。

\begin{remark}
	虽然我们称之为回调“函数”，但事实上Keras的回调函数是一个类，回调函数只是习惯性称呼
\end{remark}
\section{回调函数}
\subsection{Callback}\label{sec:obj23}

keras.callbacks.Callback()
这是回调函数的抽象类，定义新的回调函数必须继承自该类

类属性
\begin{itemize}
\item params：字典，训练参数集（如信息显示方法verbosity，batch大小，epoch数）
\item model：keras.models.Model对象，为正在训练的模型的引用
\end{itemize}

回调函数以字典logs为参数，该字典包含了一系列与当前batch或epoch相关的信息。

目前，模型的.fit()中有下列参数会被记录到logs中：
\begin{itemize}
\item 在每个epoch的结尾处（on\_epoch\_end），logs将包含训练的正确率和误差，acc和loss，如果指定了验证集，还会包含验证集正确率和误差val\_acc)和val\_loss，val\_acc还额外需要在.compile中启用metrics=['accuracy']。
\item 在每个batch的开始处（on\_batch\_begin）：logs包含size，即当前batch的样本数
\item 在每个batch的结尾处（on\_batch\_end）：logs包含loss，若启用accuracy则还包含acc
\end{itemize}

\subsection{BaseLogger}\label{sec:obj24}
\begin{python}
keras.callbacks.BaseLogger()
\end{python}
该回调函数用来对每个epoch累加metrics指定的监视指标的epoch平均值

该回调函数在每个Keras模型中都会被自动调用

\subsection{ProgbarLogger}\label{sec:obj25}
\begin{python}
keras.callbacks.ProgbarLogger()
\end{python}
该回调函数用来将metrics指定的监视指标输出到标准输出上

\subsection{History}\label{sec:obj26}
\begin{python}
keras.callbacks.History()
\end{python}
该回调函数在Keras模型上会被自动调用，History对象即为fit方法的返回值

\subsection{ModelCheckpoint}\label{sec:obj27}
\begin{itemize}
\item keras.callbacks.ModelCheckpoint(filepath, monitor='val\_loss', verbose=0, save\_best\_only=False, save\_weights\_only=False, mode='auto', period=1)
\end{itemize}

该回调函数将在每个epoch后保存模型到filepath

filepath可以是格式化的字符串，里面的占位符将会被epoch值和传入on\_epoch\_end的logs关键字所填入

例如，filepath若为weights.{epoch:02d-{val\_loss:.2f}}.hdf5，则会生成对应epoch和验证集loss的多个文件。

参数
\begin{itemize}
\item filename：字符串，保存模型的路径
\item monitor：需要监视的值
\item verbose：信息展示模式，0或1
\item save\_best\_only：当设置为True时，将只保存在验证集上性能最好的模型
mode：‘auto’，‘min’，‘max’之一，在save\_best\_only=True时决定性能最佳模型的评判准则，例如，当监测值为val\_acc时，模式应为max，当检测值为val\_loss时，模式应为min。在auto模式下，评价准则由被监测值的名字自动推断。
\item save\_weights\_only：若设置为True，则只保存模型权重，否则将保存整个模型（包括模型结构，配置信息等）
\item period：CheckPoint之间的间隔的epoch数
\end{itemize}

\subsection{EarlyStopping}\label{sec:obj28}
\begin{python}
keras.callbacks.EarlyStopping(monitor='val_loss', patience=0, verbose=0, mode='auto')
\end{python}
当监测值不再改善时，该回调函数将中止训练

参数
\begin{itemize}
\item monitor：需要监视的量
\item patience：当early stop被激活（如发现loss相比上一个epoch训练没有下降），则经过patience个epoch后停止训练。
\item verbose：信息展示模式
\item mode：‘auto’，‘min’，‘max’之一，在min模式下，如果检测值停止下降则中止训练。在max模式下，当检测值不再上升则停止训练。
\end{itemize}

\subsection{RemoteMonitor}\label{sec:obj29}
\begin{python}
keras.callbacks.RemoteMonitor(root='http://localhost:9000')
\end{python}
该回调函数用于向服务器发送事件流，该回调函数需要requests库

参数
\begin{itemize}
\item root：该参数为根url，回调函数将在每个epoch后把产生的事件流发送到该地址，事件将被发往root + '/publish/epoch/end/'。发送方法为HTTP POST，其data字段的数据是按JSON格式编码的事件字典。
\end{itemize}

\subsection{LearningRateScheduler}\label{sec:obj30}
\begin{python}
keras.callbacks.LearningRateScheduler(schedule)
\end{python}
该回调函数是学习率调度器

参数
\begin{itemize}
\item schedule：函数，该函数以epoch号为参数（从0算起的整数），返回一个新学习率（浮点数）
\end{itemize}
\subsection{TensorBoard}\label{sec:obj31}
\begin{python}
keras.callbacks.TensorBoard(log_dir='./logs', histogram_freq=0, write_graph=True, write_images=False, embeddings_freq=0, embeddings_layer_names=None, embeddings_metadata=None)
\end{python}
该回调函数是一个可视化的展示器

TensorBoard是TensorFlow提供的可视化工具，该回调函数将日志信息写入TensorBorad，使得你可以动态的观察训练和测试指标的图像以及不同层的激活值直方图。

如果已经通过pip安装了TensorFlow，我们可通过下面的命令启动TensorBoard：
\begin{python}
tensorboard --logdir=/full_path_to_your_logs
\end{python}

更多的参考信息，请点击\href{https://www.tensorflow.org/get_started/summaries_and_tensorboard}{这里}

参数
\begin{itemize}
\item log\_dir：保存日志文件的地址，该文件将被TensorBoard解析以用于可视化
\item histogram\_freq：计算各个层激活值直方图的频率（每多少个epoch计算一次），如果设置为0则不计算。
\item write\_graph: 是否在Tensorboard上可视化图，当设为True时，log文件可能会很大
\item write\_images: 是否将模型权重以图片的形式可视化
\item embeddings\_freq: 依据该频率(以epoch为单位)筛选保存的embedding层
\item embeddings\_layer\_names:要观察的层名称的列表，若设置为None或空列表，则所有embedding层都将被观察。
\item embeddings\_metadata: 字典，将层名称映射为包含该embedding层元数据的文件名，参考
\end{itemize}
这里获得元数据文件格式的细节。如果所有的embedding层都使用相同的元数据文件，则可传递字符串。
\subsection{ReduceLROnPlateau}\label{sec:obj32}
\begin{python}
keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=0.1, patience=10, verbose=0, mode='auto', epsilon=0.0001, cooldown=0, min_lr=0)
\end{python}
当评价指标不在提升时，减少学习率

当学习停滞时，减少2倍或10倍的学习率常常能获得较好的效果。该回调函数检测指标的情况，如果在patience个epoch中看不到模型性能提升，则减少学习率

参数
\begin{itemize}
\item monitor：被监测的量
\item factor：每次减少学习率的因子，学习率将以lr = lr*factor的形式被减少
\item patience：当patience个epoch过去而模型性能不提升时，学习率减少的动作会被触发
\item mode：‘auto’，‘min’，‘max’之一，在min模式下，如果检测值触发学习率减少。在max模式下，当检测值不再上升则触发学习率减少。
\item epsilon：阈值，用来确定是否进入检测值的“平原区”
\item cooldown：学习率减少后，会经过cooldown个epoch才重新进行正常操作
\item min\_lr：学习率的下限
\end{itemize}

\section{CSVLogger}\label{sec:obj33}
\begin{python}
keras.callbacks.CSVLogger(filename, separator=',', append=False)
\end{python}
将epoch的训练结果保存在csv文件中，支持所有可被转换为string的值，包括1D的可迭代数值如np.ndarray.

参数
\begin{itemize}
\item fiename：保存的csv文件名，如run/log.csv
\item separator：字符串，csv分隔符
\item append：默认为False，为True时csv文件如果存在则继续写入，为False时总是覆盖csv文件
\end{itemize}

\section{LambdaCallback}\label{sec:obj34}
\begin{python}
keras.callbacks.LambdaCallback(on_epoch_begin=None, on_epoch_end=None, on_batch_begin=None, on_batch_end=None, on_train_begin=None, on_train_end=None)
\end{python}
用于创建简单的callback的callback类

该callback的匿名函数将会在适当的时候调用，注意，该回调函数假定了一些位置参数on\_eopoch\_begin和on\_epoch\_end假定输入的参数是epoch, logs. on\_batch\_begin和on\_batch\_end假定输入的参数是batch, logs，on\_train\_begin和on\_train\_end假定输入的参数是logs

参数
\begin{itemize}
\item on\_epoch\_begin: 在每个epoch开始时调用
\item on\_epoch\_end: 在每个epoch结束时调用
\item on\_batch\_begin: 在每个batch开始时调用
\item on\_batch\_end: 在每个batch结束时调用
\item on\_train\_begin: 在训练开始时调用
\item on\_train\_end: 在训练结束时调用
\end{itemize}

示例
\begin{python}
# Print the batch number at the beginning of every batch.
batch_print_callback = LambdaCallback(
    on_batch_begin=lambda batch,logs: print(batch))

# Plot the loss after every epoch.
import numpy as np
import matplotlib.pyplot as plt
plot_loss_callback = LambdaCallback(
    on_epoch_end=lambda epoch, logs: plt.plot(np.arange(epoch),
                      logs['loss']))

# Terminate some processes after having finished model training.
processes = ...
cleanup_callback = LambdaCallback(
    on_train_end=lambda logs: [
    p.terminate() for p in processes if p.is_alive()])

model.fit(...,
      callbacks=[batch_print_callback,
         plot_loss_callback,
         cleanup_callback])
\end{python}
\section{编写自己的回调函数}\label{sec:obj35}

我们可以通过继承keras.callbacks.Callback编写自己的回调函数，回调函数通过类成员self.model访问访问，该成员是模型的一个引用。

这里是一个简单的保存每个batch的loss的回调函数：
\begin{python}
class LossHistory(keras.callbacks.Callback):
    def on_train_begin(self, logs={}):
        self.losses = []

    def on_batch_end(self, batch, logs={}):
        self.losses.append(logs.get('loss'))
\end{python}
例子：记录损失函数的历史数据
\begin{python}
class LossHistory(keras.callbacks.Callback):
    def on_train_begin(self, logs={}):
        self.losses = []

    def on_batch_end(self, batch, logs={}):
        self.losses.append(logs.get('loss'))

model = Sequential()
model.add(Dense(10, input_dim=784, kernel_initializer='uniform'))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')

history = LossHistory()
model.fit(X_train, Y_train, batch_size=128, epochs=20, verbose=0, callbacks=[history])

print history.losses
# outputs
'''
[0.66047596406559383, 0.3547245744908703, ..., 0.25953155204159617, 0.25901699725311789]
\end{python}
例子：模型检查点
\begin{python}
from keras.callbacks import ModelCheckpoint

model = Sequential()
model.add(Dense(10, input_dim=784, kernel_initializer='uniform'))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')

'''
saves the model weights after each epoch if the validation loss decreased
'''
checkpointer = ModelCheckpoint(filepath="/tmp/weights.hdf5", verbose=1, save_best_only=True)
model.fit(X_train, Y_train, batch_size=128, epochs=20, verbose=0, validation_data=(X_test, Y_test), callbacks=[checkpointer])
\end{python}
\chapter{Application应用}

Kera的应用模块Application提供了带有预训练权重的Keras模型，这些模型可以用来进行预测、特征提取和finetune

模型的预训练权重将下载到~/.keras/models/并在载入模型时自动载入

\section{可用的模型}

应用于图像分类的模型,权重训练自ImageNet： Xception VGG16 VGG19 ResNet50 InceptionV3 MobileNet

所有的这些模型(除了Xception和MobileNet)都兼容Theano和Tensorflow，并会自动基于~/.keras/keras.json的Keras的图像维度进行自动设置。例如，如果你设置data\_format="channel\_last"，则加载的模型将按照TensorFlow的维度顺序来构造，即“Width-Height-Depth”的顺序

Xception模型仅在TensorFlow下可用，因为它依赖的SeparableConvolution层仅在TensorFlow可用。MobileNet仅在TensorFlow下可用，因为它依赖的DepethwiseConvolution层仅在TF下可用。

以上模型（暂时除了MobileNet）的预训练权重可以在我的百度网盘下载，如果有更新的话会在这里报告

\section{图片分类模型的示例}

利用ResNet50网络进行ImageNet分类
\begin{python}
from keras.applications.resnet50 import ResNet50
from keras.preprocessing import image
from keras.applications.resnet50 import preprocess_input, decode_predictions
import numpy as np

model = ResNet50(weights='imagenet')

img_path = 'elephant.jpg'
img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)

preds = model.predict(x)
# decode the results into a list of tuples (class, description, probability)
# (one such list for each sample in the batch)
print('Predicted:', decode_predictions(preds, top=3)[0])
# Predicted: [(u'n02504013', u'Indian_elephant', 0.82658225), (u'n01871265', u'tusker', 0.1122357), (u'n02504458', u'African_elephant', 0.061040461)]
\end{python}
利用VGG16提取特征
\begin{python}
from keras.applications.vgg16 import VGG16
from keras.preprocessing import image
from keras.applications.vgg16 import preprocess_input
import numpy as np

model = VGG16(weights='imagenet', include_top=False)

img_path = 'elephant.jpg'
img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)
features = model.predict(x)
\end{python}
从VGG19的任意中间层中抽取特征
\begin{python}
from keras.applications.vgg19 import VGG19
from keras.preprocessing import image
from keras.applications.vgg19 import preprocess_input
from keras.models import Model
import numpy as np

base_model = VGG19(weights='imagenet')
model = Model(inputs=base_model.input, outputs=base_model.get_layer('block4_pool').output)

img_path = 'elephant.jpg'
img = image.load_img(img_path, target_size=(224, 224))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
x = preprocess_input(x)

block4_pool_features = model.predict(x)
\end{python}
\section{在新类别上fine-tune inceptionV3}
\begin{python}
from keras.applications.inception_v3 import InceptionV3
from keras.preprocessing import image
from keras.models import Model
from keras.layers import Dense, GlobalAveragePooling2D
from keras import backend as K

# create the base pre-trained model
base_model = InceptionV3(weights='imagenet', include_top=False)

# add a global spatial average pooling layer
x = base_model.output
x = GlobalAveragePooling2D()(x)
# let's add a fully-connected layer
x = Dense(1024, activation='relu')(x)
# and a logistic layer -- let's say we have 200 classes
predictions = Dense(200, activation='softmax')(x)

# this is the model we will train
model = Model(inputs=base_model.input, outputs=predictions)

# first: train only the top layers (which were randomly initialized)
# i.e. freeze all convolutional InceptionV3 layers
for layer in base_model.layers:
    layer.trainable = False

# compile the model (should be done *after* setting layers to non-trainable)
model.compile(optimizer='rmsprop', loss='categorical_crossentropy')

# train the model on the new data for a few epochs
model.fit_generator(...)

# at this point, the top layers are well trained and we can start fine-tuning
# convolutional layers from inception V3. We will freeze the bottom N layers
# and train the remaining top layers.

# let's visualize layer names and layer indices to see how many layers
# we should freeze:
for i, layer in enumerate(base_model.layers):
   print(i, layer.name)

# we chose to train the top 2 inception blocks, i.e. we will freeze
# the first 249 layers and unfreeze the rest:
for layer in model.layers[:249]:
   layer.trainable = False
for layer in model.layers[249:]:
   layer.trainable = True

# we need to recompile the model for these modifications to take effect
# we use SGD with a low learning rate
from keras.optimizers import SGD
model.compile(optimizer=SGD(lr=0.0001, momentum=0.9), loss='categorical_crossentropy')

# we train our model again (this time fine-tuning the top 2 inception blocks
# alongside the top Dense layers
model.fit_generator(...)
\end{python}
在定制的输入tensor上构建InceptionV3
\begin{python}
from keras.applications.inception_v3 import InceptionV3
from keras.layers import Input

# this could also be the output a different Keras model or layer
input_tensor = Input(shape=(224, 224, 3))  # this assumes K.image_data_format() == 'channels_last'

model = InceptionV3(input_tensor=input_tensor, weights='imagenet', include_top=True)
\end{python}
\section{模型文档}
\begin{itemize}
\item Xception
\item VGG16
\item VGG19
\item ResNet50
\item InceptionV3
\item MobileNet
\end{itemize}


\section{Xception模型}
\begin{python}
keras.applications.xception.Xception(include_top=True, weights='imagenet',input_tensor=None, input_shape=None,pooling=None, classes=1000)
\end{python}
Xception V1 模型, 权重由ImageNet训练而言

在ImageNet上,该模型取得了验证集top1 0.790和top5 0.945的正确率

注意,该模型目前仅能以TensorFlow为后端使用,由于它依赖于"SeparableConvolution"层,目前该模型只支持channels\_last的维度顺序(width, height, channels)

默认输入图片大小为299x299

参数
\begin{itemize}
\item include\_top：是否保留顶层的3个全连接网络
\item weights：None代表随机初始化，即不加载预训练权重。'imagenet'代表加载预训练权重
\item input\_tensor：可填入Keras tensor作为模型的图像输出tensor
\item input\_shape：可选，仅当include\_top=False有效，应为长为3的tuple，指明输入图片的shape，图片的宽高必须大于71，如(150,150,3)
\item pooling：当include\_top=False时，该参数指定了池化方式。None代表不池化，最后一个卷积层的输出为4D张量。‘avg’代表全局平均池化，‘max’代表全局最大值池化。
\item classes：可选，图片分类的类别数，仅当include\_top=True并且不加载预训练权重时可用。
\end{itemize}
返回值

Keras 模型对象

参考文献
\begin{itemize}
\item \href{https://arxiv.org/abs/1610.02357}{Xception: Deep Learning with Depthwise Separable} Convolutions
\end{itemize}

License

预训练权重由我们自己训练而来，基于MIT license发布


\section{VGG16模型}

\begin{python}
keras.applications.vgg16.VGG16(include_top=True, weights='imagenet',
                                input_tensor=None, input_shape=None,
                                pooling=None,
                                classes=1000)
\end{python}
VGG16模型,权重由ImageNet训练而来

该模型再Theano和TensorFlow后端均可使用,并接受channels\_first和channels\_last两种输入维度顺序

模型的默认输入尺寸时224x224

参数
\begin{itemize}
\item include\_top：是否保留顶层的3个全连接网络
\item weights：None代表随机初始化，即不加载预训练权重。'imagenet'代表加载预训练权重
\item input\_tensor：可填入Keras tensor作为模型的图像输出tensor
\item input\_shape：可选，仅当include\_top=False有效，应为长为3的tuple，指明输入图片的shape，图片的宽高必须大于48，如(200,200,3)
\end{itemize}

返回值
\begin{itemize}
\item pooling：当include\_top=False时，该参数指定了池化方式。None代表不池化，最后一个卷积层的输出为4D张量。‘avg’代表全局平均池化，‘max’代表全局最大值池化。
\item classes：可选，图片分类的类别数，仅当include\_top=True并且不加载预训练权重时可用。
\end{itemize}

Keras 模型对象

参考文献
\begin{itemize}
\item \href{https://arxiv.org/abs/1409.1556}{Very Deep Convolutional Networks for Large-Scale Image Recognition}：如果在研究中使用了VGG，请引用该文
\end{itemize}

License

预训练权重由牛津VGG组发布的预训练权重移植而来，基于Creative Commons Attribution License


\section{VGG19模型}
\begin{python}

keras.applications.vgg19.VGG19(include_top=True, weights='imagenet',
                                input_tensor=None, input_shape=None,
                                pooling=None,
                                classes=1000)
\end{python}
VGG19模型,权重由ImageNet训练而来

该模型在Theano和TensorFlow后端均可使用,并接受channels\_first和channels\_last两种输入维度顺序

模型的默认输入尺寸时224x224

参数
\begin{itemize}
\item include\_top：是否保留顶层的3个全连接网络
\item weights：None代表随机初始化，即不加载预训练权重。'imagenet'代表加载预训练权重
\item input\_tensor：可填入Keras tensor作为模型的图像输出tensor
\item input\_shape：可选，仅当include\_top=False有效，应为长为3的tuple，指明输入图片的shape，图片的宽高必须大于48，如(200,200,3)
\item pooling：当include\_top=False时，该参数指定了池化方式。None代表不池化，最后一个卷积层的输出为4D张量。‘avg’代表全局平均池化，‘max’代表全局最大值池化。
\item classes：可选，图片分类的类别数，仅当include\_top=True并且不加载预训练权重时可用。
\end{itemize}

返回值


Keras 模型对象

参考文献
\begin{itemize}
\item \href{https://arxiv.org/abs/1409.1556}{Very Deep Convolutional Networks for Large-Scale Image Recognition}：如果在研究中使用了VGG，请引用该文
\end{itemize}

License

预训练权重由牛津VGG组发布的预训练权重移植而来，基于Creative Commons Attribution License


\section{ResNet50模型}
\begin{python}

keras.applications.resnet50.ResNet50(include_top=True, weights='imagenet',input_tensor=None, input_shape=None,pooling=None,classes=1000)
\end{python}
50层残差网络模型,权重训练自ImageNet

该模型在Theano和TensorFlow后端均可使用,并接受channels\_first和channels\_last两种输入维度顺序

模型的默认输入尺寸时224x224

参数
\begin{itemize}
\item include\_top：是否保留顶层的全连接网络
\item weights：None代表随机初始化，即不加载预训练权重。'imagenet'代表加载预训练权重
\item input\_tensor：可填入Keras tensor作为模型的图像输出tensor
\item input\_shape：可选，仅当include\_top=False有效，应为长为3的tuple，指明输入图片的shape，图片的宽高必须大于197，如(200,200,3)
\item pooling：当include\_top=False时，该参数指定了池化方式。None代表不池化，最后一个卷积层的输出为4D张量。‘avg’代表全局平均池化，‘max’代表全局最大值池化。
\item classes：可选，图片分类的类别数，仅当include\_top=True并且不加载预训练权重时可用。
\end{itemize}

返回值

Keras 模型对象

参考文献
\begin{itemize}
\item \href{https://arxiv.org/abs/1512.03385}{Deep Residual Learning for Image Recognition}：如果在研究中使用了ResNet50，请引用该文
\end{itemize}

License

预训练权重由\href{https://github.com/KaimingHe/deep-residual-networks}{Kaiming He}发布的预训练权重移植而来，基于\href{https://github.com/KaimingHe/deep-residual-networks/blob/master/LICENSE}{MIT License}


\section{InceptionV3模型}
\begin{python}

keras.applications.inception_v3.InceptionV3(include_top=True,
                                            weights='imagenet',
                                            input_tensor=None,
                                            input_shape=None,
                                            pooling=None,
                                            classes=1000)
\end{python}
InceptionV3网络,权重训练自ImageNet

该模型在Theano和TensorFlow后端均可使用,并接受channels\_first和channels\_last两种输入维度顺序

模型的默认输入尺寸时299x299

参数
\begin{itemize}
\item include\_top：是否保留顶层的全连接网络
\item weights：None代表随机初始化，即不加载预训练权重。'imagenet'代表加载预训练权重
\item input\_tensor：可填入Keras tensor作为模型的图像输出tensor
\item input\_shape：可选，仅当include\_top=False有效，应为长为3的tuple，指明输入图片的shape，图片的宽高必须大于197，如(200,200,3)
\item pooling：当include\_top=False时，该参数指定了池化方式。None代表不池化，最后一个卷积层的输出为4D张量。‘avg’代表全局平均池化，‘max’代表全局最大值池化。
\item classes：可选，图片分类的类别数，仅当include\_top=True并且不加载预训练权重时可用。
\end{itemize}

返回值

Keras 模型对象

参考文献
\begin{itemize}
\item \href{http://arxiv.org/abs/1512.00567}{Rethinking the Inception Architecture for Computer Vision}：如果在研究中使用了InceptionV3，请引用该文
\end{itemize}

License

预训练权重由我们自己训练而来，基于MIT License


\section{MobileNet模型}

\begin{python}
keras.applications.mobilenet.MobileNet(input_shape=None, alpha=1.0, depth_multiplier=1, dropout=1e-3, include_top=True, weights='imagenet', input_tensor=None, pooling=None, classes=1000)
\end{python}
MobileNet网络,权重训练自ImageNet

该模型仅在TensorFlow后端均可使用,因此仅channels\_last维度顺序可用。当需要以load\_model()加载MobileNet时，需要在custom\_object中传入relu6和DepthwiseConv2D，即：
\begin{python}
model = load_model('mobilenet.h5', custom_objects={
                   'relu6': mobilenet.relu6,
                   'DepthwiseConv2D': mobilenet.DepthwiseConv2D})
\end{python}
模型的默认输入尺寸时224x224

参数
\begin{itemize}
\item include\_top：是否保留顶层的全连接网络
\item weights：None代表随机初始化，即不加载预训练权重。'imagenet'代表加载预训练权重
\item input\_tensor：可填入Keras tensor作为模型的图像输出tensor
\item input\_shape：可选，仅当include\_top=False有效，应为长为3的tuple，指明输入图片的shape，图片的宽高必须大于197，如(200,200,3)
\item pooling：当include\_top=False时，该参数指定了池化方式。None代表不池化，最后一个卷积层的输出为4D张量。‘avg’代表全局平均池化，‘max’代表全局最大值池化。
\item classes：可选，图片分类的类别数，仅当include\_top=True并且不加载预训练权重时可用。
\item alpha: 控制网络的宽度：
  \begin{itemize}
    \item 如果alpha<1，则同比例的减少每层的滤波器个数
    \item 如果alpha>1，则同比例增加每层的滤波器个数
    \item 如果alpha=1，使用默认的滤波器个数
  \end{itemize}
\item depth\_multiplier：depthwise卷积的深度乘子，也称为（分辨率乘子）
\item dropout：dropout比例
\end{itemize}

返回值

Keras 模型对象

参考文献
\begin{itemize}
\item \href{https://arxiv.org/pdf/1704.04861.pdf}{MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications}：如果在研究中使用了MobileNet，请引用该文
\end{itemize}

License

预训练基于Apache License发布
\chapter{常用数据库}
\section{CIFAR10 小图片分类数据集}
该数据库具有50,000个32*32的彩色图片作为训练集，10,000个图片作为测试集。图片一共有10个类别。
使用方法
\begin{python}
from keras.datasets import cifar10

(X_train, y_train), (X_test, y_test) = cifar10.load_data()
\end{python}
返回值：
两个Tuple
X\_train和X\_test是形如（nb\_samples, 3, 32, 32）的RGB三通道图像数据，数据类型是无符号8位整形（uint8）
Y\_train和 Y\_test是形如（nb\_samples,）标签数据，标签的范围是0~9
\section{CIFAR100 小图片分类数据库}
该数据库具有50,000个32*32的彩色图片作为训练集，10,000个图片作为测试集。图片一共有100个类别，每个类别有600张图片。这100个类别又分为20个大类。

使用方法
\begin{python}
from keras.datasets import cifar100

(X_train, y_train), (X_test, y_test) = cifar100.load_data(label_mode='fine')
\end{python}
参数
\begin{itemize}
\item label\_mode：为‘fine’或‘coarse’之一，控制标签的精细度，‘fine’获得的标签是100个小类的标签，‘coarse’获得的标签是大类的标签
\end{itemize}

返回值

两个Tuple,(X\_train, y\_train), (X\_test, y\_test)，其中
\begin{itemize}
\item X\_train和X\_test：是形如（nb\_samples, 3, 32, 32）的RGB三通道图像数据，数据类型是无符号8位整形（uint8）
\item y\_train和y\_test：是形如（nb\_samples,）标签数据，标签的范围是0~9
\end{itemize}

\section{IMDB影评倾向分类}

本数据库含有来自IMDB的25,000条影评，被标记为正面/负面两种评价。影评已被预处理为词下标构成的序列。方便起见，单词的下标基于它在数据集中出现的频率标定，例如整数3所编码的词为数据集中第3常出现的词。这样的组织方法使得用户可以快速完成诸如“只考虑最常出现的10,000个词，但不考虑最常出现的20个词”这样的操作

按照惯例，0不代表任何特定的词，而用来编码任何未知单词

使用方法
\begin{python}
from keras.datasets import imdb
(X_train, y_train), (X_test, y_test) = imdb.load_data(path="imdb.npz",
          nb_words=None,
          skip_top=0,
          maxlen=None,
          test_split=0.1)
          seed=113,
          start_char=1,
          oov_char=2,
          index_from=3)
\end{python}
参数
\begin{itemize}
\item path：如果你在本机上已有此数据集（位于`~/.keras/datasets/`+path），则载入。否则数据将下载到该目录下
\item nb\_words：整数或None，要考虑的最常见的单词数，序列中任何出现频率更低的单词将会被编码为oov\_char的值。
\item skip\_top：整数，忽略最常出现的若干单词，这些单词将会被编码为oov\_char的值
\item maxlen：整数，最大序列长度，任何长度大于此值的序列将被截断
\item seed：整数，用于数据重排的随机数种子
\item start\_char：字符，序列的起始将以该字符标记，默认为1因为0通常用作padding
\item oov\_char：整数，因nb\_words或skip\_top限制而cut掉的单词将被该字符代替
\item index\_from：整数，真实的单词（而不是类似于start\_char的特殊占位符）将从这个下标开始
\end{itemize}

返回值

两个Tuple,(X\_train, y\_train), (X\_test, y\_test)，其中
\begin{itemize}
\item X\_train和X\_test：序列的列表，每个序列都是词下标的列表。如果指定了nb\_words，则序列中可能的最大下标为nb\_words-1。如果指定了maxlen，则序列的最大可能长度为maxlen
\item y\_train和y\_test：为序列的标签，是一个二值list
\end{itemize}

\section{路透社新闻主题分类}

本数据库包含来自路透社的11,228条新闻，分为了46个主题。与IMDB库一样，每条新闻被编码为一个词下标的序列。

使用方法
\begin{python}
from keras.datasets import reuters
(X_train, y_train), (X_test, y_test) = reuters.load_data(path="reuters.npz",
          nb_words=None,
          skip_top=0,
          maxlen=None,
          test_split=0.2,
          seed=113,
          start_char=1,
          oov_char=2,
          index_from=3)
\end{python}
参数的含义与IMDB同名参数相同，唯一多的参数是： test\_split，用于指定从原数据中分割出作为测试集的比例。该数据库支持获取用于编码序列的词下标：

word\_index = reuters.get\_word\_index(path="reuters\_word\_index.json")
上面代码的返回值是一个以单词为关键字，以其下标为值的字典。例如，word\_index['giraffe']的值可能为1234

参数
\begin{itemize}
\item path：如果你在本机上已有此数据集（位于'~/.keras/datasets/'+path），则载入。否则数据将下载到该目录下
\end{itemize}

\section{MNIST手写数字识别}

本数据库有60,000个用于训练的28*28的灰度手写数字图片，10,000个测试图片

使用方法
\begin{python}
from keras.datasets import mnist

(X_train, y_train), (X_test, y_test) = mnist.load_data()
\end{python}
参数
\begin{itemize}
\item path：如果你在本机上已有此数据集（位于'~/.keras/datasets/'+path），则载入。否则数据将下载到该目录下
\end{itemize}
返回值

两个Tuple,(X\_train, y\_train), (X\_test, y\_test)，其中
\begin{itemize}
\item X\_train和X\_test：是形如（nb\_samples, 28, 28）的灰度图片数据，数据类型是无符号8位整形（uint8）
\item y\_train和y\_test：是形如（nb\_samples,）标签数据，标签的范围是0~9
\end{itemize}

数据库将会被下载到'~/.keras/datasets/'+path

\section{Boston房屋价格回归数据集}

本数据集由StatLib库取得，由CMU维护。每个样本都是1970s晚期波士顿郊区的不同位置，每条数据含有13个属性，目标值是该位置房子的房价中位数（千dollar）。

使用方法
\begin{python}
from keras.datasets import boston_housing

(x_train, y_train), (x_test, y_test) = boston_housing.load_data()
\end{python}
参数：
\begin{itemize}
    \item path：数据存放位置，默认'~/.keras/datasets/'+path

        (默认为path='boston\_housing.npz')
    \item seed：随机数种子(默认为seed=113)
    \item test\_split：分割测试集的比例(默认test\_split=0.2)
\end{itemize}

返回值

两个Tuple,(X\_train, y\_train), (X\_test, y\_test)
\chapter{模型可视化}

keras.utils.vis\_utils模块提供了画出Keras模型的函数（利用graphviz）

该函数将画出模型结构图，并保存成图片：
\begin{python}
from keras.utils import plot_model
plot_model(model, to_file='model.png')
\end{python}
plot\_model接收两个可选参数：
\begin{itemize}
\item show\_shapes：指定是否显示输出数据的形状，默认为False
\item show\_layer\_names:指定是否显示层名称,默认为True
\end{itemize}

我们也可以直接获取一个pydot.Graph对象，然后按照自己的需要配置它，例如，如果要在ipython中展示图片
\begin{python}
from IPython.display import SVG
from keras.utils.vis_utils import model_to_dot
SVG(model_to_dot(model).create(prog='dot', format='svg'))
\end{python}
\begin{remark}
依赖 pydot-ng 和 graphviz，若出现错误，用命令行输入pip install pydot-ng \& brew install graphviz
\end{remark}
\chapter{utils 工具}\label{ch:utils}

本模块提供了一系列有用工具

\section{CustomObjectScope}
\begin{python}
keras.utils.generic_utils.CustomObjectScope()
\end{python}
提供定制类的作用域，在该作用域内全局定制类能够被更改，但在作用域结束后将回到初始状态。 以with声明开头的代码将能够通过名字访问定制类的实例，在with的作用范围，这些定制类的变动将一直持续，在with作用域结束后，全局定制类的实例将回归其在with作用域前的状态。
\begin{python}
with CustomObjectScope({"MyObject":MyObject}):
    layer = Dense(..., W_regularizer="MyObject")
    # save, load, etc. will recognize custom object by name
\end{python}
\section{HDF5Matrix}
\begin{python}
keras.utils.io_utils.HDF5Matrix(datapath, dataset, start=0, end=None, normalizer=None)
\end{python}
这是一个使用HDF5数据集代替Numpy数组的方法

提供start和end参数可以进行切片，另外，还可以提供一个正规化函数或匿名函数，该函数将会在每片数据检索时自动调用。
\begin{python}
x_data = HDF5Matrix('input/file.hdf5', 'data')
model.predict(x_data)
\end{python}
\begin{itemize}
\item datapath: 字符串，HDF5文件的路径
\item dataset: 字符串，在datapath路径下HDF5数据库名字
\item start: 整数，想要的数据切片起点
\item end: 整数，想要的数据切片终点
\item normalizer: 在每个切片数据检索时自动调用的函数对象
\end{itemize}

\section{Sequence}
\begin{python}
keras.utils.data_utils.Sequence()
\end{python}
序列数据的基类，例如一个数据集。 每个Sequence必须实现\_\_getitem\_\_和\_\_len\_\_方法

下面是一个例子：
\begin{python}
from skimage.io import imread
from skimage.transform import resize
import numpy as np

__Here, `x_set` is list of path to the images__

# and `y_set` are the associated classes.

class CIFAR10Sequence(Sequence):
    def __init__(self, x_set, y_set, batch_size):
        self.X,self.y = x_set,y_set
        self.batch_size = batch_size

    def __len__(self):
        return len(self.X) // self.batch_size

    def __getitem__(self,idx):
        batch_x = self.X[idx*self.batch_size:(idx+1)*self.batch_size]
        batch_y = self.y[idx*self.batch_size:(idx+1)*self.batch_size]

        return np.array([
        resize(imread(file_name), (200,200))
           for file_name in batch_x]), np.array(batch_y)
\end{python}
\section{to\_categorical}
\begin{python}
to_categorical(y, num_classes=None)
\end{python}
将类别向量(从0到nb\_classes的整数向量)映射为二值类别矩阵, 用于应用到以categorical\_crossentropy为目标函数的模型中.

参数
\begin{itemize}
\item y: 类别向量
\item num\_classes:总共类别数
\end{itemize}

\section{normalize}
\begin{python}
normalize(x, axis=-1, order=2)
\end{python}
对numpy数组规范化，返回规范化后的数组

参数
\begin{itemize}
\item x：待规范化的数据
\item axis: 规范化的轴
\item order：规范化方法，如2为L2范数
\end{itemize}

\section{custom\_object\_scope}
\begin{python}
custom_object_scope()
\end{python}
提供定制类的作用域，在该作用域内全局定制类能够被更改，但在作用域结束后将回到初始状态。 以with声明开头的代码将能够通过名字访问定制类的实例，在with的作用范围，这些定制类的变动将一直持续，在with作用域结束后，全局定制类的实例将回归其在with作用域前的状态。

本函数返回CustomObjectScope对象
\begin{python}
with custom_object_scope({"MyObject":MyObject}):
    layer = Dense(..., W_regularizer="MyObject")
    # save, load, etc. will recognize custom object by name
\end{python}
\section{get\_custom\_objects}
\begin{python}
get_custom_objects()
\end{python}
检索全局定制类，推荐利用custom\_object\_scope更新和清理定制对象，但get\_custom\_objects可被直接用于访问\_GLOBAL\_CUSTOM\_OBJECTS。本函数返回从名称到类别映射的全局字典。
\begin{python}
get_custom_objects().clear()
get_custom_objects()["MyObject"] = MyObject
\end{python}
\section{convert\_all\_kernels\_in\_model}
\begin{python}
convert_all_kernels_in_model(model)
\end{python}
将模型中全部卷积核在Theano和TensorFlow模式中切换

\section{plot\_model}
\begin{python}
plot_model(model, to_file='model.png', show_shapes=False, show_layer_names=True)
\end{python}
绘制模型的结构图

\section{serialize\_keras\_object}
\begin{python}
serialize_keras_object(instance)
\end{python}
将keras对象序列化

\section{deserialize\_keras\_object}
\begin{python}
eserialize_keras_object(identifier, module_objects=None, custom_objects=None, printable_module_name='object')
\end{python}
从序列中恢复keras对象

\section{get\_file}
\begin{python}
get_file(fname, origin, untar=False, md5_hash=None, file_hash=None, cache_subdir='datasets', hash_algorithm='auto', extract=False, archive_format='auto', cache_dir=None)
\end{python}
从给定的URL中下载文件, 可以传递MD5值用于数据校验(下载后或已经缓存的数据均可)

默认情况下文件会被下载到~/.keras中的cache\_subdir文件夹，并将其文件名设为fname，因此例如一个文件example.txt最终将会被存放在`~/.keras/datasets/example.txt~

tar,tar.gz.tar.bz和zip格式的文件可以被提取，提供哈希码可以在下载后校验文件。命令喊程序shasum和sha256sum可以计算哈希值。

参数
\begin{itemize}
\item fname: 文件名，如果指定了绝对路径/path/to/file.txt,则文件将会保存到该位置。
\item origin: 文件的URL地址
\item untar: 布尔值,是否要进行解压
\item md5\_hash: MD5哈希值,用于数据校验，支持sha256和md5哈希
\item cache\_subdir: 用于缓存数据的文件夹，若指定绝对路径/path/to/folder则将存放在该路径下。
\item hash\_algorithm: 选择文件校验的哈希算法，可选项有'md5', 'sha256', 和'auto'. 默认'auto'自动检测使用的哈希算法
\item extract: 若为True则试图提取文件，例如tar或zip tries extracting the file as an Archive, like tar or zip.
\item archive\_format: 试图提取的文件格式，可选为'auto', 'tar', 'zip', 和None. 'tar' 包括tar, tar.gz, tar.bz文件. 默认'auto'是['tar', 'zip']. None或空列表将返回没有匹配。
\item cache\_dir: 缓存文件存放地在，参考FAQ
\end{itemize}

返回值

下载后的文件地址
\chapter{Keras后端}

\section{什么是“后端”}

Keras是一个模型级的库，提供了快速构建深度学习网络的模块。Keras并不处理如张量乘法、卷积等底层操作。这些操作依赖于某种特定的、优化良好的张量操作库。Keras依赖于处理张量的库就称为“后端引擎”。Keras提供了三种后端引擎Theano/Tensorflow/CNTK，并将其函数统一封装，使得用户可以以同一个接口调用不同后端引擎的函数
\begin{itemize}
\item Theano是一个开源的符号主义张量操作框架，由蒙特利尔大学LISA/MILA实验室开发。
\item TensorFlow是一个符号主义的张量操作框架，由Google开发。
\item CNTK是一个由微软开发的商业级工具包。
\end{itemize}

在未来，我们有可能要添加更多的后端选项。

\section{切换后端}

注意：Windows用户请把\$Home改为\%USERPROFILE\%

如果你至少运行过一次Keras，你将在下面的目录下找到Keras的配置文件：

\$HOME/.keras/keras.json

如果该目录下没有该文件，你可以手动创建一个

文件的默认配置如下：
\begin{minted}[linenos]{json}
{
    "image_data_format": "channels_last",
    "epsilon": 1e-07,
    "floatx": "float32",
    "backend": "tensorflow"
}
\end{minted}
将backend字段的值改写为你需要使用的后端：theano或tensorflow或者CNTK，即可完成后端的切换

我们也可以通过定义环境变量KERAS\_BACKEND来覆盖上面配置文件中定义的后端：
\begin{bashcode}
KERAS_BACKEND=tensorflow python -c "from keras import backend;"
Using TensorFlow backend.
\end{bashcode}
\section{keras.json 细节}
\begin{minted}[linenos]{json}
{
    "image_data_format": "channels_last",
    "epsilon": 1e-07,
    "floatx": "float32",
    "backend": "tensorflow"
}
\end{minted}
你可以更改以上~/.keras/keras.json中的配置
\begin{itemize}
\item iamge\_data\_format：字符串，"channels\_last"或"channels\_first"，该选项指定了Keras将要使用的维度顺序，可通过keras.backend.image\_data\_format()来获取当前的维度顺序。对2D数据来说，"channels\_last"假定维度顺序为(rows,cols,channels)而"channels\_first"假定维度顺序为(channels, rows, cols)。对3D数据而言，"channels\_last"假定(conv\_dim1, conv\_dim2, conv\_dim3, channels)，"channels\_first"则是(channels, conv\_dim1, conv\_dim2, conv\_dim3)
\item epsilon：浮点数，防止除0错误的小数字
\item floatx：字符串，"float16", "float32", "float64"之一，为浮点数精度
\item backend：字符串，所使用的后端，为"tensorflow"或"theano"
\end{itemize}

\section{使用抽象的Keras后端来编写代码}

如果你希望你编写的Keras模块能够同时在Theano和TensorFlow两个后端上使用，你可以通过Keras后端接口来编写代码，这里是一个简介：
\pythoninline{from keras import backend as K}
下面的代码实例化了一个输入占位符，等价于tf.placeholder() ，T.matrix()，T.tensor3()等
\begin{python}
input = K.placeholder(shape=(2, 4, 5))
# also works:
input = K.placeholder(shape=(None, 4, 5))
# also works:
input = K.placeholder(ndim=3)
\end{python}
下面的代码实例化了一个共享变量（shared），等价于tf.variable()或 theano.shared()
\begin{python}
val = np.random.random((3, 4, 5))
var = K.variable(value=val)

# all-zeros variable:
var = K.zeros(shape=(3, 4, 5))
# all-ones:
var = K.ones(shape=(3, 4, 5))
\end{python}
大多数你需要的张量操作都可以通过统一的Keras后端接口完成，而不关心具体执行这些操作的是Theano还是TensorFlow
\begin{python}
a = b + c * K.abs(d)
c = K.dot(a, K.transpose(b))
a = K.sum(b, axis=2)
a = K.softmax(b)
a = concatenate([b, c], axis=-1)
# etc...
\end{python}
\section{Kera后端函数}

backend

backend()
返回当前后端

epsilon

epsilon()
以数值形式返回一个（一般来说很小的）数，用以防止除0错误

set\_epsilon

set\_epsilon(e)
设置在数值表达式中使用的fuzz factor，用于防止除0错误，该值应该是一个较小的浮点数，示例：
\begin{bashcode}
>>> from keras import backend as K
>>> K.epsilon()
1e-08
>>> K.set_epsilon(1e-05)
>>> K.epsilon()
1e-05
\end{bashcode}
\textbf{floatx}

floatx()
返回默认的浮点数数据类型，为字符串，如 'float16', 'float32', 'float64'

\textbf{set\_floatx(floatx)}

floatx()
设置默认的浮点数数据类型，为字符串，如 'float16', 'float32', 'float64',示例：
\begin{bashcode}
>>> from keras import backend as K
>>> K.floatx()
'float32'
>>> K.set_floatx('float16')
>>> K.floatx()
'float16'
\end{bashcode}
\textbf{cast\_to\_floatx}

\textbf{cast\_to\_floatx(x)}
将numpy array转换为默认的Keras floatx类型，x为numpy array，返回值也为numpy array但其数据类型变为floatx。示例：
\begin{bashcode}
>>> from keras import backend as K
>>> K.floatx()
'float32'
>>> arr = numpy.array([1.0, 2.0], dtype='float64')
>>> arr.dtype
dtype('float64')
>>> new_arr = K.cast_to_floatx(arr)
>>> new_arr
array([ 1.,  2.], dtype=float32)
>>> new_arr.dtype
dtype('float32')
\end{bashcode}
\textbf{image\_data\_format}

image\_data\_format()
返回默认的图像的维度顺序（‘channels\_last’或‘channels\_first’）

\textbf{set\_image\_data\_format}

set\_image\_data\_format(data\_format)
设置图像的维度顺序（‘tf’或‘th’）,示例：
\begin{bashcode}
from keras import backend as K K.image_data_format() 'channels_first' K.set_image_data_format('channels_last') K.image_data_format() 'channels_last'
\end{bashcode}
\begin{python}
# is_keras_tensor()
is_keras_tensor(x)
\end{python}
判断x是否是keras tensor对象的谓词函数
\begin{bashcode}
>>> from keras import backend as K
>>> np_var = numpy.array([1, 2])
>>> K.is_keras_tensor(np_var)
False
>>> keras_var = K.variable(np_var)
>>> K.is_keras_tensor(keras_var)  # A variable is not a Tensor.
False
>>> keras_placeholder = K.placeholder(shape=(2, 4, 5))
>>> K.is_keras_tensor(keras_placeholder)  # A placeholder is a Tensor.
True
\end{bashcode}
\textbf{get\_uid}

get\_uid(prefix='')
获得默认计算图的uid，依据给定的前缀提供一个唯一的UID，参数为表示前缀的字符串，返回值为整数.

\textbf{reset\_uids}

reset\_uids()
重置图的标识符

\textbf{is\_keras\_tensor}

is\_keras\_tensor(x)
判断x是否是一个Keras tensor，返回一个布尔值，示例
\begin{bashcode}
>>> from keras import backend as K
>>> np_var = numpy.array([1, 2])
>>> K.is_keras_tensor(np_var)
False
>>> keras_var = K.variable(np_var)
>>> K.is_keras_tensor(keras_var)  # A variable is not a Tensor.
False
>>> keras_placeholder = K.placeholder(shape=(2, 4, 5))
>>> K.is_keras_tensor(keras_placeholder)  # A placeholder is a Tensor.
True
\end{bashcode}
\textbf{clear\_session}

clear\_session()
结束当前的TF计算图，并新建一个。有效的避免模型/层的混乱

\textbf{manual\_variable\_initialization}

manual\_variable\_initialization(value)
指出变量应该以其默认值被初始化还是由用户手动初始化，参数value为布尔值，默认False代表变量由其默认值初始化

\textbf{learning\_phase}

learning\_phase()
返回训练模式/测试模式的flag，该flag是一个用以传入Keras模型的标记，以决定当前模型执行于训练模式下还是测试模式下

\textbf{set\_learning\_phase}

set\_learning\_phase()
设置训练模式/测试模式0或1

\textbf{is\_sparse}

is\_sparse(tensor)
判断一个tensor是不是一个稀疏的tensor(稀不稀疏由tensor的类型决定，而不是tensor实际上有多稀疏)，返回值是一个布尔值，示例：
\begin{bashcode}
>>> from keras import backend as K
>>> a = K.placeholder((2, 2), sparse=False)
>>> print(K.is_sparse(a))
False
>>> b = K.placeholder((2, 2), sparse=True)
>>> print(K.is_sparse(b))
True
\end{bashcode}
\textbf{to\_dense}

to\_dense(tensor)
将一个稀疏tensor转换一个不稀疏的tensor并返回之，示例：
\begin{bashcode}
>>> from keras import backend as K
>>> b = K.placeholder((2, 2), sparse=True)
>>> print(K.is_sparse(b))
True
>>> c = K.to_dense(b)
>>> print(K.is_sparse(c))
False
\end{bashcode}
\textbf{variable}

variable(value, dtype='float32', name=None)
实例化一个张量，返回之

参数：
\begin{itemize}
\item value：用来初始化张量的值
\item dtype：张量数据类型
\item name：张量的名字（可选）
\end{itemize}

示例：
\begin{bashcode}
>>> from keras import backend as K
>>> val = np.array([[1, 2], [3, 4]])
>>> kvar = K.variable(value=val, dtype='float64', name='example_var')
>>> K.dtype(kvar)
'float64'
>>> print(kvar)
example_var
>>> kvar.eval()
array([[ 1.,  2.],
   [ 3.,  4.]])
\end{bashcode}
\textbf{placeholder}

placeholder(shape=None, ndim=None, dtype='float32', name=None)
实例化一个占位符，返回之

参数：
\begin{itemize}
\item shape：占位符的shape（整数tuple，可能包含None）
\item ndim: 占位符张量的阶数，要初始化一个占位符，至少指定shape和ndim之一，如果都指定则使用shape
\item dtype: 占位符数据类型
\item name: 占位符名称（可选）
\end{itemize}

示例：
\begin{bashcode}
>>> from keras import backend as K
>>> input_ph = K.placeholder(shape=(2, 4, 5))
>>> input_ph._keras_shape
(2, 4, 5)
>>> input_ph
<tf.Tensor 'Placeholder_4:0' shape=(2, 4, 5) dtype=float32>
\end{bashcode}
\textbf{shape}

shape(x)
返回一个张量的符号shape，符号shape的意思是返回值本身也是一个tensor，示例：
\begin{bashcode}
>>> from keras import backend as K
>>> tf_session = K.get_session()
>>> val = np.array([[1, 2], [3, 4]])
>>> kvar = K.variable(value=val)
>>> input = keras.backend.placeholder(shape=(2, 4, 5))
>>> K.shape(kvar)
<tf.Tensor 'Shape_8:0' shape=(2,) dtype=int32>
>>> K.shape(input)
<tf.Tensor 'Shape_9:0' shape=(3,) dtype=int32>
__To get integer shape (Instead, you can use K.int_shape(x))__

>>> K.shape(kvar).eval(session=tf_session)
array([2, 2], dtype=int32)
>>> K.shape(input).eval(session=tf_session)
array([2, 4, 5], dtype=int32)
\end{bashcode}
\textbf{int\_shape}

int\_shape(x)
以整数Tuple或None的形式返回张量shape，示例：
\begin{bashcode}
>>> from keras import backend as K
>>> input = K.placeholder(shape=(2, 4, 5))
>>> K.int_shape(input)
(2, 4, 5)
>>> val = np.array([[1, 2], [3, 4]])
>>> kvar = K.variable(value=val)
>>> K.int_shape(kvar)
(2, 2)
\end{bashcode}
\textbf{ndim}

ndim(x)
返回张量的阶数，为整数，示例：
\begin{bashcode}
>>> from keras import backend as K
>>> input = K.placeholder(shape=(2, 4, 5))
>>> val = np.array([[1, 2], [3, 4]])
>>> kvar = K.variable(value=val)
>>> K.ndim(input)
3
>>> K.ndim(kvar)
2
\end{bashcode}
\textbf{dtype}

dtype(x)
返回张量的数据类型，为字符串，示例：
\begin{bashcode}
>>> from keras import backend as K
>>> K.dtype(K.placeholder(shape=(2,4,5)))
'float32'
>>> K.dtype(K.placeholder(shape=(2,4,5), dtype='float32'))
'float32'
>>> K.dtype(K.placeholder(shape=(2,4,5), dtype='float64'))
'float64'
__Keras variable__

>>> kvar = K.variable(np.array([[1, 2], [3, 4]]))
>>> K.dtype(kvar)
'float32_ref'
>>> kvar = K.variable(np.array([[1, 2], [3, 4]]), dtype='float32')
>>> K.dtype(kvar)
'float32_ref'
\end{bashcode}
\textbf{eval}

eval(x)
求得张量的值，返回一个Numpy array，示例：
\begin{bashcode}
>>> from keras import backend as K
>>> kvar = K.variable(np.array([[1, 2], [3, 4]]), dtype='float32')
>>> K.eval(kvar)
array([[ 1.,  2.],
   [ 3.,  4.]], dtype=float32)
\end{bashcode}
\textbf{zeros}

zeros(shape, dtype='float32', name=None)
生成一个全0张量，示例：
\begin{bashcode}
>>> from keras import backend as K
>>> kvar = K.zeros((3,4))
>>> K.eval(kvar)
array([[ 0.,  0.,  0.,  0.],
   [ 0.,  0.,  0.,  0.],
   [ 0.,  0.,  0.,  0.]], dtype=float32)
\end{bashcode}
\textbf{ones}

ones(shape, dtype='float32', name=None)
生成一个全1张量，示例
\begin{bashcode}
>>> from keras import backend as K
>>> kvar = K.ones((3,4))
>>> K.eval(kvar)
array([[ 1.,  1.,  1.,  1.],
   [ 1.,  1.,  1.,  1.],
   [ 1.,  1.,  1.,  1.]], dtype=float32)
\end{bashcode}
\textbf{eye}

eye(size, dtype='float32', name=None)
生成一个单位矩阵，示例：
\begin{bashcode}
>>> from keras import backend as K
>>> kvar = K.eye(3)
>>> K.eval(kvar)
array([[ 1.,  0.,  0.],
   [ 0.,  1.,  0.],
   [ 0.,  0.,  1.]], dtype=float32)
\end{bashcode}
\textbf{zeros\_like}

zeros\_like(x, name=None)
生成与另一个张量x的shape相同的全0张量，示例：
\begin{bashcode}
>>> from keras import backend as K
>>> kvar = K.variable(np.random.random((2,3)))
>>> kvar_zeros = K.zeros_like(kvar)
>>> K.eval(kvar_zeros)
array([[ 0.,  0.,  0.],
   [ 0.,  0.,  0.]], dtype=float32)
\end{bashcode}
\textbf{ones\_like}

ones\_like(x, name=None)
生成与另一个张量shape相同的全1张量，示例：
\begin{bashcode}
>>> from keras import backend as K
>>> kvar = K.variable(np.random.random((2,3)))
>>> kvar_ones = K.ones_like(kvar)
>>> K.eval(kvar_ones)
array([[ 1.,  1.,  1.],
   [ 1.,  1.,  1.]], dtype=float32)
\end{bashcode}
\textbf{random\_uniform\_variable}

random\_uniform\_variable(shape, low, high, dtype=None, name=None, seed=None)
初始化一个Keras变量，其数值为从一个均匀分布中采样的样本，返回之。

参数：
\begin{itemize}
\item shape：张量shape
\item low：浮点数，均匀分布之下界
\item high：浮点数，均匀分布之上界
\item dtype：数据类型
\item name：张量名
\item seed：随机数种子
\end{itemize}

示例：
\begin{bashcode}
>>> kvar = K.random_uniform_variable((2,3), 0, 1)
>>> kvar
<tensorflow.python.ops.variables.Variable object at 0x10ab40b10>
>>> K.eval(kvar)
array([[ 0.10940075,  0.10047495,  0.476143  ],
   [ 0.66137183,  0.00869417,  0.89220798]], dtype=float32)
\end{bashcode}
\textbf{count\_params}

count\_params(x)
返回张量中标量的个数，示例：
\begin{bashcode}
>>> kvar = K.zeros((2,3))
>>> K.count_params(kvar)
6
>>> K.eval(kvar)
array([[ 0.,  0.,  0.],
   [ 0.,  0.,  0.]], dtype=float32)
\end{bashcode}
\textbf{cast}

cast(x, dtype)
改变张量的数据类型，dtype只能是float16, float32或float64之一，示例：
\begin{bashcode}
>>> from keras import backend as K
>>> input = K.placeholder((2, 3), dtype='float32')
>>> input
<tf.Tensor 'Placeholder_2:0' shape=(2, 3) dtype=float32>
__It doesn't work in-place as below.__

>>> K.cast(input, dtype='float16')
<tf.Tensor 'Cast_1:0' shape=(2, 3) dtype=float16>
>>> input
<tf.Tensor 'Placeholder_2:0' shape=(2, 3) dtype=float32>
__you need to assign it.__

>>> input = K.cast(input, dtype='float16')
>>> input
<tf.Tensor 'Cast_2:0' shape=(2, 3) dtype=float16>```
\end{bashcode}
\textbf{update}

update(x, new\_x)
用new\_x更新x

\textbf{update\_add}

update\_add(x, increment)
通过将x增加increment更新x

\textbf{update\_sub}

update\_sub(x, decrement)
通过将x减少decrement更新x

\textbf{moving\_average\_update}

moving\_average\_update(x, value, momentum)
含义暂不明确

\textbf{dot}

dot(x, y)
求两个张量的乘积。当试图计算两个N阶张量的乘积时，与Theano行为相同，如(2, 3).(4, 3, 5) = (2, 4, 5))，示例：
\begin{bashcode}
>>> x = K.placeholder(shape=(2, 3))
>>> y = K.placeholder(shape=(3, 4))
>>> xy = K.dot(x, y)
>>> xy
<tf.Tensor 'MatMul_9:0' shape=(2, 4) dtype=float32>
>>> x = K.placeholder(shape=(32, 28, 3))
>>> y = K.placeholder(shape=(3, 4))
>>> xy = K.dot(x, y)
>>> xy
<tf.Tensor 'MatMul_9:0' shape=(32, 28, 4) dtype=float32>
\end{bashcode}
Theano-like的行为示例：
\begin{bashcode}
>>> x = K.random_uniform_variable(shape=(2, 3), low=0, high=1)
>>> y = K.ones((4, 3, 5))
>>> xy = K.dot(x, y)
>>> K.int_shape(xy)
(2, 4, 5)
\end{bashcode}
\textbf{batch\_dot}

batch\_dot(x, y, axes=None)
按批进行张量乘法，该函数用于计算x和y的点积，其中x和y都是成batch出现的数据。即它的数据shape形如(batch\_size,:)。batch\_dot将产生比输入张量维度低的张量，如果张量的维度被减至1，则通过expand\_dims保证其维度至少为2 例如，假设x = [[1, 2],[3,4]] ， y = [[5, 6],[7, 8]]，则batch\_dot(x, y, axes=1) = [[17, 53]]，即x.dot(y.T)的主对角元素，此过程中我们没有计算过反对角元素的值

参数：
\begin{itemize}
\item x,y：阶数大于等于2的张量，在tensorflow下，只支持大于等于3阶的张量
\item axes：目标结果的维度，为整数或整数列表，axes[0]和axes[1]应相同
\end{itemize}
示例： 假设x=[[1,2],[3,4]]，y=[[5,6],[7,8]]，则batch\_dot(x, y, axes=1)为[[17, 53]]，恰好为x.dot(y.T)的主对角元，整个过程没有计算反对角元的元素。

我们做一下shape的推导，假设x是一个shape为(100,20)的tensor，y是一个shape为(100,30,20)的tensor，假设axes=(1,2)，则输出tensor的shape通过循环x.shape和y.shape确定：
\begin{itemize}
\item x.shape[0]：值为100，加入到输入shape里
\item x.shape[1]：20，不加入输出shape里，因为该维度的值会被求和(dot\_axes[0]=1)
\item y.shape[0]：值为100，不加入到输出shape里，y的第一维总是被忽略
\item y.shape[1]：30，加入到输出shape里
\item y.shape[2]：20，不加到output shape里，y的第二个维度会被求和(dot\_axes[1]=2)
结果为(100, 30)
\end{itemize}
\begin{python}
>>> x_batch = K.ones(shape=(32, 20, 1))
>>> y_batch = K.ones(shape=(32, 30, 20))
>>> xy_batch_dot = K.batch_dot(x_batch, y_batch, axes=[1, 2])
>>> K.int_shape(xy_batch_dot)
(32, 1, 30)
\end{python}
\textbf{transpose}

transpose(x)
张量转置，返回转置后的tensor，示例：
\begin{bashcode}
>>> var = K.variable([[1, 2, 3], [4, 5, 6]])
>>> K.eval(var)
array([[ 1.,  2.,  3.],
   [ 4.,  5.,  6.]], dtype=float32)
>>> var_transposed = K.transpose(var)
>>> K.eval(var_transposed)
array([[ 1.,  4.],
   [ 2.,  5.],
   [ 3.,  6.]], dtype=float32)

>>> input = K.placeholder((2, 3))
>>> input
<tf.Tensor 'Placeholder_11:0' shape=(2, 3) dtype=float32>
>>> input_transposed = K.transpose(input)
>>> input_transposed
<tf.Tensor 'transpose_4:0' shape=(3, 2) dtype=float32>
\end{bashcode}
\textbf{gather}

gather(reference, indices)
在给定的张量中检索给定下标的向量

参数：
\begin{itemize}
\item reference：张量
\item indices：整数张量，其元素为要查询的下标
\end{itemize}

返回值：一个与reference数据类型相同的张量

\textbf{max}

max(x, axis=None, keepdims=False)
求张量中的最大值

\textbf{min}

min(x, axis=None, keepdims=False)
求张量中的最小值

\textbf{sum}

sum(x, axis=None, keepdims=False)
在给定轴上计算张量中元素之和

\textbf{prod}

prod(x, axis=None, keepdims=False)
在给定轴上计算张量中元素之积

\textbf{cumsum}

cumsum(x, axis=0)
在给定轴上求张量的累积和

\textbf{cumprod}

cumprod(x, axis=0)
在给定轴上求张量的累积积

\textbf{var}

var(x, axis=None, keepdims=False)
在给定轴上计算张量方差

\textbf{std}

std(x, axis=None, keepdims=False)
在给定轴上求张量元素之标准差

\textbf{mean}

mean(x, axis=None, keepdims=False)
在给定轴上求张量元素之均值

\textbf{any}

any(x, axis=None, keepdims=False)
按位或，返回数据类型为uint8的张量（元素为0或1）

\textbf{all}

any(x, axis=None, keepdims=False)
按位与，返回类型为uint8de tensor

\textbf{argmax}

argmax(x, axis=-1)
在给定轴上求张量之最大元素下标

\textbf{argmin}

argmin(x, axis=-1)
在给定轴上求张量之最小元素下标

\textbf{square}

square(x)
逐元素平方

\textbf{abs}

abs(x)
逐元素绝对值

\textbf{sqrt}

sqrt(x)
逐元素开方

\textbf{exp}

exp(x)
逐元素求自然指数

\textbf{log}

log(x)
逐元素求自然对数

\textbf{logsumexp}

logsumexp(x, axis=None, keepdims=False)
在给定轴上计算log(sum(exp()))，该函数在数值稳定性上超过直接计算log(sum(exp()))，可以避免由exp和log导致的上溢和下溢

\textbf{round}

round(x)
逐元素四舍五入

\textbf{sign}

sign(x)
逐元素求元素的符号（+1或-1）

\textbf{pow}

pow(x, a)
逐元素求x的a次方

\textbf{clip}

clip(x, min\_value, max\_value)
逐元素clip（将超出指定范围的数强制变为边界值）

\textbf{equal}

equal(x, y)
逐元素判相等关系，返回布尔张量

\textbf{not\_equal}

not\_equal(x, y)
逐元素判不等关系，返回布尔张量

\textbf{greater}

greater(x,y)
逐元素判断x>y关系，返回布尔张量

\textbf{greater\_equal}

greater\_equal(x,y)
逐元素判断x>=y关系，返回布尔张量

\textbf{lesser}

lesser(x,y)
逐元素判断x<y关系，返回布尔张量

\textbf{lesser\_equal}

lesser\_equal(x,y)
逐元素判断x<=y关系，返回布尔张量

\textbf{maximum}

maximum(x, y)
逐元素取两个张量的最大值

\textbf{minimum}

minimum(x, y)
逐元素取两个张量的最小值

\textbf{sin}

sin(x)
逐元素求正弦值

\textbf{cos}

cos(x)
逐元素求余弦值

\textbf{normalize\_batch\_in\_training}

normalize\_batch\_in\_training(x, gamma, beta, reduction\_axes, epsilon=0.0001)
对一个batch数据先计算其均值和方差，然后再进行batch\_normalization

\textbf{batch\_normalization}

batch\_normalization(x, mean, var, beta, gamma, epsilon=0.0001)
对一个batch的数据进行batch\_normalization，计算公式为： output = (x-mean)/(sqrt(var)+epsilon)*gamma+beta

\textbf{concatenate}

concatenate(tensors, axis=-1)
在给定轴上将一个列表中的张量串联为一个张量 specified axis

\textbf{reshape}

reshape(x, shape)
将张量的shape变换为指定shape

\textbf{permute\_dimensions}

permute\_dimensions(x, pattern)
按照给定的模式重排一个张量的轴

参数：
\begin{itemize}
\item pattern：代表维度下标的tuple如(0, 2, 1)
\end{itemize}
\textbf{resize\_images}

resize\_images(X, height\_factor, width\_factor, dim\_ordering)
依据给定的缩放因子，改变一个batch图片的shape，参数中的两个因子都为正整数，图片的排列顺序与维度的模式相关，如‘th’和‘tf’

\textbf{resize\_volumes}

resize\_volumes(X, depth\_factor, height\_factor, width\_factor, dim\_ordering)
依据给定的缩放因子，改变一个5D张量数据的shape，参数中的两个因子都为正整数，图片的排列顺序与维度的模式相关，如‘th’和‘tf’。5D数据的形式是batch, channels, depth, height, width或batch, depth, height, width, channels

\textbf{repeat\_elements}

repeat\_elements(x, rep, axis)
在给定轴上重复张量元素rep次，与np.repeat类似。例如，若xshape(s1, s2, s3)并且给定轴为axis=1`，输出张量的shape为`(s1, s2 * rep, s3)

\textbf{repeat}

repeat(x, n)
重复2D张量，例如若xshape是(samples, dim)且n为2，则输出张量的shape是(samples, 2, dim)

\textbf{arange}

arange(start, stop=None, step=1, dtype='int32')
生成1D的整数序列张量，该函数的参数与Theano的arange函数含义相同，如果只有一个参数被提供了，那么它实际上就是stop参数的值

为了与tensorflow的默认保持匹配，函数返回张量的默认数据类型是int32

\textbf{tile}

tile(x, n)
将x在各个维度上重复n次，x为张量，n为与x维度数目相同的列表

\textbf{batch\_flatten}

batch\_flatten(x)
将一个n阶张量转变为2阶张量，其第一维度保留不变

\textbf{expand\_dims}

\textbf{expand\_dims(x, dim=-1)}
在下标为dim的轴上增加一维

\textbf{squeeze}

squeeze(x, axis)
将下标为axis的一维从张量中移除

\textbf{temporal\_padding}

temporal\_padding(x, padding=1)
向3D张量中间的那个维度的左右两端填充padding个0值

\textbf{asymmetric\_temporal\_padding}

asymmetric\_temporal\_padding(x, left\_pad=1, right\_pad=1)
向3D张量中间的那个维度的一端填充padding个0值

\textbf{spatial\_2d\_padding}

spatial\_2d\_padding(x, padding=(1, 1), dim\_ordering='th')
向4D张量第二和第三维度的左右两端填充padding[0]和padding[1]个0值

\textbf{spatial\_3d\_padding}

spatial\_3d\_padding(x, padding=(1, 1, 1), dim\_ordering='th')
向5D张量深度、高度和宽度三个维度上填充padding[0]，padding[1]和padding[2]个0值

\textbf{stack}

stack(x, axis=0)
将一个列表中维度数目为R的张量堆积起来形成维度为R+1的新张量

\textbf{one-hot}

one\_hot(indices, nb\_classes)
输入为n维的整数张量，形如(batch\_size, dim1, dim2, ... dim(n-1))，输出为(n+1)维的one-hot编码，形如(batch\_size, dim1, dim2, ... dim(n-1), nb\_classes)

reverse

\textbf{reverse(x, axes)}
将一个张量在给定轴上反转

\textbf{get\_value}

\textbf{get\_value(x)}
以Numpy array的形式返回张量的值

\textbf{batch\_get\_value}

batch\_get\_value(x)
以Numpy array list的形式返回多个张量的值

\textbf{set\_value}

set\_value(x, value)
从numpy array将值载入张量中

\textbf{batch\_set\_value}

batch\_set\_value(tuples)
将多个值载入多个张量变量中

参数：
\begin{itemize}
\item tuples: 列表，其中的元素形如(tensor, value)。value是要载入的Numpy array数据
\end{itemize}

\textbf{print\_tensor}

print\_tensor(x, message='')
在求值时打印张量的信息，并返回原张量

\textbf{function}

function(inputs, outputs, updates=[])
实例化一个Keras函数

参数：
\begin{itemize}
\item inputs:：列表，其元素为占位符或张量变量
\item outputs：输出张量的列表
\item updates：列表，其元素是形如(old\_tensor, new\_tensor)的tuple.
\end{itemize}

\textbf{gradients}

gradients(loss, variables)
返回loss函数关于variables的梯度，variables为张量变量的列表

\textbf{stop\_gradient}

stop\_gradient(variables)
Returns variables but with zero gradient with respect to every other variables.

\textbf{rnn}

rnn(step\_function, inputs, initial\_states, go\_backwards=False, mask=None, constants=None, unroll=False, input\_length=None)
在张量的时间维上迭代

参数：
\begin{itemize}
\item inputs： 形如(samples, time, ...)的时域信号的张量，阶数至少为3
\item step\_function：每个时间步要执行的函数 其参数：
\item input：形如(samples, ...)的张量，不含时间维，代表某个时间步时一个batch的样本
\item states：张量列表 其返回值：
\item output：形如(samples, ...)的张量
\item new\_states：张量列表，与‘states’的长度相同
\item initial\_states：形如(samples, ...)的张量，包含了step\_function状态的初始值。
\item go\_backwards：布尔值，若设为True，则逆向迭代序列
\item mask：形如(samples, time, 1)的二值张量，需要屏蔽的数据元素上值为1
\item constants：按时间步传递给函数的常数列表
\item unroll：当使用TensorFlow时，RNN总是展开的。当使用Theano时，设置该值为True将展开递归网络
\item input\_length：使用TensorFlow时不需要此值，在使用Theano时，如果要展开递归网络，必须指定输入序列
\end{itemize}

返回值：形如(last\_output, outputs, new\_states)的tuple
\begin{itemize}
\item last\_output：rnn最后的输出，形如(samples, ...)
\item outputs：形如(samples, time, ...)的张量，每个在[s,t]点的输出对应于样本s在t时间的输出
\item new\_states: 列表，其元素为形如(samples, ...)的张量，代表每个样本的最后一个状态
\end{itemize}

\textbf{switch}

switch(condition, then\_expression, else\_expression)
依据给定的条件‘condition’（整数或布尔值）在两个表达式之间切换，注意两个表达式都应该是具有同样shape的符号化张量表达式

参数：
begin{itemize}
item condition：标量张量
item then\_expression：TensorFlow表达式
item else\_expression: TensorFlow表达式
end{itemize}

\textbf{in\_train\_phase}

in\_train\_phase(x, alt)
如果处于训练模式，则选择x，否则选择alt，注意alt应该与x的shape相同

\textbf{in\_test\_phase}

in\_test\_phase(x, alt)
如果处于测试模式，则选择x，否则选择alt，注意alt应该与x的shape相同

\textbf{relu}

relu(x, alpha=0.0, max\_value=None)
修正线性单元

参数：
\begin{itemize}
\item alpha：负半区斜率
\item max\_value: 饱和门限
\end{itemize}

\textbf{elu}

elu(x, alpha=1.0)
指数线性单元

参数：
\begin{itemize}
\item x：输入张量
\item alpha: 标量
\end{itemize}

\textbf{softmax}

softmax(x)
返回张量的softmax值

\textbf{softplus}

softplus(x)
返回张量的softplus值

\textbf{softsign}

softsign(x)
返回张量的softsign值

\textbf{categorical\_crossentropy}

categorical\_crossentropy(output, target, from\_logits=False)
计算输出张量和目标张量的Categorical crossentropy（类别交叉熵），目标张量与输出张量必须shape相同

\textbf{sparse\_categorical\_crossentropy}

sparse\_categorical\_crossentropy(output, target, from\_logits=False)
计算输出张量和目标张量的Categorical crossentropy（类别交叉熵），目标张量必须是整型张量

\textbf{binary\_crossentropy}

binary\_crossentropy(output, target, from\_logits=False)
计算输出张量和目标张量的交叉熵

\textbf{sigmoid}

sigmoid(x)
逐元素计算sigmoid值

\textbf{hard\_sigmoid}

hard\_sigmoid(x)
该函数是分段线性近似的sigmoid，计算速度更快

\textbf{tanh}

tanh(x)
逐元素计算sigmoid值

\textbf{dropout}

dropout(x, level, seed=None)
随机将x中一定比例的值设置为0，并放缩整个tensor

参数：
\begin{itemize}
\item x：张量
\item level：x中设置成0的元素比例
\item seed：随机数种子
\end{itemize}

\textbf{l2\_normalize}

l2\_normalize(x, axis)
在给定轴上对张量进行L2范数规范化

\textbf{in\_top\_k}

in\_top\_k(predictions, targets, k)
判断目标是否在predictions的前k大值位置

参数：
\begin{itemize}
\item predictions：预测值张量, shape为(batch\_size, classes), 数据类型float32
\item targets：真值张量, shape为(batch\_size,),数据类型为int32或int64
\item k：整数
\end{itemize}

\textbf{conv1d}

conv1d(x, kernel, strides=1, border\_mode='valid', image\_shape=None, filter\_shape=None)
1D卷积

参数：
\begin{itemize}
\item kernel：卷积核张量
\item strides：步长，整型
\item border\_mode：“same”，“valid”之一的字符串
\end{itemize}

\textbf{conv2d}

conv2d(x, kernel, strides=(1, 1), border\_mode='valid', dim\_ordering='th', image\_shape=None, filter\_shape=None)
2D卷积

参数：
\begin{itemize}
\item kernel：卷积核张量
\item strides：步长，长为2的tuple
\item border\_mode：“same”，“valid”之一的字符串
\item dim\_ordering：“tf”和“th”之一，维度排列顺序
\end{itemize}

\textbf{deconv2d}

deconv2d(x, kernel, output\_shape, strides=(1, 1), border\_mode='valid', dim\_ordering='th', image\_shape=None, filter\_shape=None)
2D反卷积（转置卷积）

参数：
\begin{itemize}
\item x：输入张量
\item kernel：卷积核张量
\item output\_shape: 输出shape的1D的整数张量
\item strides：步长，tuple类型
\item border\_mode：“same”或“valid”
\item dim\_ordering：“tf”或“th”
\end{itemize}

\textbf{conv3d}

conv3d(x, kernel, strides=(1, 1, 1), border\_mode='valid', dim\_ordering='th', volume\_shape=None, filter\_shape=None)
3D卷积

参数：
\begin{itemize}
\item x：输入张量
\item kernel：卷积核张量
\item strides：步长，tuple类型
\item border\_mode：“same”或“valid”
\item dim\_ordering：“tf”或“th”
\end{itemize}

\textbf{pool2d}

pool2d(x, pool\_size, strides=(1, 1), border\_mode='valid', dim\_ordering='th', pool\_mode='max')
2D池化

参数：
\begin{itemize}
\item pool\_size：含有两个整数的tuple，池的大小
\item strides：含有两个整数的tuple，步长
\item border\_mode：“same”，“valid”之一的字符串
\item dim\_ordering：“tf”和“th”之一，维度排列顺序
\item pool\_mode: “max”，“avg”之一，池化方式
\end{itemize}

\textbf{pool3d}

pool3d(x, pool\_size, strides=(1, 1, 1), border\_mode='valid', dim\_ordering='th', pool\_mode='max')
3D池化

参数：
\begin{itemize}
\item pool\_size：含有3个整数的tuple，池的大小
\item strides：含有3个整数的tuple，步长
\item border\_mode：“same”，“valid”之一的字符串
\item dim\_ordering：“tf”和“th”之一，维度排列顺序
\item pool\_mode: “max”，“avg”之一，池化方式
\end{itemize}

\textbf{bias\_add}

bias\_add(x, bias, data\_format=None)
为张量增加一个偏置项

\textbf{random\_normal}

random\_normal(shape, mean=0.0, stddev=1.0, dtype=None, seed=None)
返回具有正态分布值的张量，mean和stddev为均值和标准差

\textbf{random\_uniform}

random\_uniform(shape, minval=0.0, maxval=1.0, dtype=None, seed=None)
返回具有均匀分布值的张量，minval和maxval是均匀分布的下上界

\textbf{random\_binomial}

random\_binomial(shape, p=0.0, dtype=None, seed=None)
返回具有二项分布值的张量，p是二项分布参数

\textbf{truncated\_normall}

truncated\_normal(shape, mean=0.0, stddev=1.0, dtype=None, seed=None)
返回具有截尾正态分布值的张量，在距离均值两个标准差之外的数据将会被截断并重新生成

\textbf{ctc\_label\_dense\_to\_sparse}

ctc\_label\_dense\_to\_sparse(labels, label\_lengths)
将ctc标签从稠密形式转换为稀疏形式

\textbf{ctc\_batch\_cost}

ctc\_batch\_cost(y\_true, y\_pred, input\_length, label\_length)
在batch上运行CTC损失算法

参数：
\begin{itemize}
\item y\_true：形如(samples，max\_tring\_length)的张量，包含标签的真值
\item y\_pred：形如(samples，time\_steps，num\_categories)的张量，包含预测值或输出的softmax值
\item input\_length：形如(samples，1)的张量，包含y\_pred中每个batch的序列长
\item label\_length：形如(samples，1)的张量，包含y\_true中每个batch的序列长
\end{itemize}

返回值：形如(samoles，1)的tensor，包含了每个元素的CTC损失

\textbf{ctc\_decode}

ctc\_decode(y\_pred, input\_length, greedy=True, beam\_width=None, dict\_seq\_lens=None, dict\_values=None)
使用贪婪算法或带约束的字典搜索算法解码softmax的输出

参数：
\begin{itemize}
\item y\_pred：形如(samples，time\_steps，num\_categories)的张量，包含预测值或输出的softmax值
\item input\_length：形如(samples，1)的张量，包含y\_pred中每个batch的序列长
\item greedy：设置为True使用贪婪算法，速度快
\item dict\_seq\_lens：dic\_values列表中各元素的长度
\item dict\_values：列表的列表，代表字典
\end{itemize}

返回值：形如(samples，time\_steps，num\_catgories)的张量，包含了路径可能性（以softmax概率的形式）。注意仍然需要一个用来取出argmax和处理空白标签的函数

\textbf{map\_fn}

map\_fn(fn, elems, name=None)
元素elems在函数fn上的映射，并返回结果

参数：
\begin{itemize}
\item fn：函数
\item elems：张量
\item name：节点的名字
\end{itemize}

返回值：返回一个张量，该张量的第一维度等于elems，第二维度取决于fn

\textbf{foldl}

foldl(fn, elems, initializer=None, name=None)
减少elems，用fn从左到右连接它们

参数：
\begin{itemize}
\item fn：函数，例如：lambda acc, x: acc + x
\item elems：张量
\item initializer：初始化的值(elems[0])
\item name：节点名
\end{itemize}

返回值：与initializer的类型和形状一致

\textbf{foldr}

foldr(fn, elems, initializer=None, name=None)
减少elems，用fn从右到左连接它们

参数：
\begin{itemize}
\item fn：函数，例如：lambda acc, x: acc + x
\item elems：张量
\item initializer：初始化的值（elems[-1]）
\item name：节点名
\end{itemize}

返回值：与initializer的类型和形状一致
